codex-xai-oauth 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.
- package/.codex-plugin/plugin.json +28 -0
- package/.mcp.json +9 -0
- package/LICENSE +21 -0
- package/README.md +134 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +5905 -0
- package/dist/codex/doctor.d.ts +12 -0
- package/dist/codex/setup.d.ts +16 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.js +33006 -0
- package/dist/openai-compat/server.d.ts +10 -0
- package/dist/version.d.ts +2 -0
- package/dist/xai/browser-oauth.d.ts +24 -0
- package/dist/xai/codex-config.d.ts +9 -0
- package/dist/xai/constants.d.ts +17 -0
- package/dist/xai/credentials.d.ts +4 -0
- package/dist/xai/device-oauth.d.ts +9 -0
- package/dist/xai/guards.d.ts +4 -0
- package/dist/xai/http.d.ts +7 -0
- package/dist/xai/index.d.ts +9 -0
- package/dist/xai/media.d.ts +35 -0
- package/dist/xai/oauth.d.ts +28 -0
- package/dist/xai/responses.d.ts +10 -0
- package/dist/xai/storage.d.ts +11 -0
- package/dist/xai/types.d.ts +58 -0
- package/package.json +58 -0
- package/skills/xai-grok/SKILL.md +49 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type CompatServer = {
|
|
2
|
+
readonly baseUrl: string;
|
|
3
|
+
readonly close: () => Promise<void>;
|
|
4
|
+
readonly port: number;
|
|
5
|
+
};
|
|
6
|
+
export declare function startOpenAiCompatServer(options?: {
|
|
7
|
+
readonly host?: string;
|
|
8
|
+
readonly port?: number;
|
|
9
|
+
}): Promise<CompatServer>;
|
|
10
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { StoredAuth } from "./types.js";
|
|
2
|
+
type CallbackResult = {
|
|
3
|
+
readonly code?: string;
|
|
4
|
+
readonly error?: string;
|
|
5
|
+
readonly error_description?: string;
|
|
6
|
+
readonly state?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function startCallbackServer(options?: {
|
|
9
|
+
readonly port?: number;
|
|
10
|
+
}): Promise<{
|
|
11
|
+
readonly close: () => Promise<void>;
|
|
12
|
+
readonly redirectUri: string;
|
|
13
|
+
readonly waitForCallback: () => Promise<CallbackResult>;
|
|
14
|
+
}>;
|
|
15
|
+
export declare function beginOAuth(options?: {
|
|
16
|
+
readonly port?: number;
|
|
17
|
+
}): Promise<{
|
|
18
|
+
readonly complete: () => Promise<StoredAuth>;
|
|
19
|
+
readonly redirectUri: string;
|
|
20
|
+
readonly state: string;
|
|
21
|
+
readonly url: string;
|
|
22
|
+
}>;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=browser-oauth.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type CodexModelProviderCredentials = {
|
|
2
|
+
readonly apiKey: string;
|
|
3
|
+
readonly baseUrl: string;
|
|
4
|
+
readonly configFile: string;
|
|
5
|
+
readonly providerName: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function codexConfigPath(): string;
|
|
8
|
+
export declare function readCodexModelProviderCredentials(path?: string): CodexModelProviderCredentials | undefined;
|
|
9
|
+
//# sourceMappingURL=codex-config.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const XAI_BASE_URL = "https://api.x.ai/v1";
|
|
2
|
+
export declare const XAI_OAUTH_ISSUER = "https://auth.x.ai";
|
|
3
|
+
export declare const XAI_OAUTH_AUTHORIZE_URL = "https://auth.x.ai/oauth2/authorize";
|
|
4
|
+
export declare const XAI_OAUTH_TOKEN_URL = "https://auth.x.ai/oauth2/token";
|
|
5
|
+
export declare const XAI_OAUTH_DEVICE_AUTHORIZATION_URL = "https://auth.x.ai/oauth2/device/code";
|
|
6
|
+
export declare const XAI_OAUTH_DISCOVERY_URL = "https://auth.x.ai/.well-known/openid-configuration";
|
|
7
|
+
export declare const XAI_OAUTH_CLIENT_ID = "b1a00492-073a-47ea-816f-4c329264a828";
|
|
8
|
+
export declare const XAI_OAUTH_SCOPE = "openid profile email offline_access grok-cli:access api:access";
|
|
9
|
+
export declare const XAI_REDIRECT_HOST = "127.0.0.1";
|
|
10
|
+
export declare const XAI_REDIRECT_PORT = 56121;
|
|
11
|
+
export declare const XAI_REDIRECT_PATH = "/callback";
|
|
12
|
+
export declare const OPENAI_COMPAT_HOST = "127.0.0.1";
|
|
13
|
+
export declare const OPENAI_COMPAT_PORT = 8787;
|
|
14
|
+
export declare const REFRESH_SKEW_MS: number;
|
|
15
|
+
export declare const USER_AGENT = "codex-xai-oauth/0.1.0";
|
|
16
|
+
export declare function xaiBaseUrl(): string;
|
|
17
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DeviceCodeResponse, StoredAuth, TokenPayload } from "./types.js";
|
|
2
|
+
export declare function requestDeviceCode(endpoint: string): Promise<DeviceCodeResponse>;
|
|
3
|
+
export declare function pollDeviceToken(device: DeviceCodeResponse, tokenEndpoint: string): Promise<TokenPayload>;
|
|
4
|
+
export declare function beginDeviceOAuth(): Promise<{
|
|
5
|
+
readonly complete: () => Promise<StoredAuth>;
|
|
6
|
+
readonly instructions: string;
|
|
7
|
+
readonly url: string;
|
|
8
|
+
}>;
|
|
9
|
+
//# sourceMappingURL=device-oauth.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
2
|
+
export declare function stringField(record: Record<string, unknown>, key: string): string | undefined;
|
|
3
|
+
export declare function numberField(record: Record<string, unknown>, key: string): number | undefined;
|
|
4
|
+
//# sourceMappingURL=guards.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function xaiRequest(path: string, options: {
|
|
2
|
+
readonly body?: Record<string, unknown>;
|
|
3
|
+
readonly headers?: Record<string, string>;
|
|
4
|
+
readonly method: "GET" | "POST";
|
|
5
|
+
readonly timeoutMs?: number;
|
|
6
|
+
}): Promise<Response>;
|
|
7
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { beginOAuth, startCallbackServer } from "./browser-oauth.js";
|
|
2
|
+
export { credentialStatus, resolveXaiCredentials } from "./credentials.js";
|
|
3
|
+
export { beginDeviceOAuth, pollDeviceToken, requestDeviceCode, } from "./device-oauth.js";
|
|
4
|
+
export { xaiImageGenerate, xaiTts, xaiVideoGenerate } from "./media.js";
|
|
5
|
+
export { buildAuthorizeUrl, discoverXaiOAuth, exchangeCodeForToken, pkcePair, refreshAccessToken, storedAuthFromToken, } from "./oauth.js";
|
|
6
|
+
export { xaiChatCompletions, xaiResponses } from "./responses.js";
|
|
7
|
+
export { authPath, defaultAuthPath, defaultGrokAuthPath, grokAuthPath, readGrokStoredAuth, readStoredAuth, writeStoredAuth, } from "./storage.js";
|
|
8
|
+
export type { CredentialStatus, DeviceCodeResponse, OpenAiChatCompletionRequest, OpenAiChatMessage, ReasoningEffort, StoredAuth, XaiCredentials, XaiResponseResult, } from "./types.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare function xaiImageGenerate(args: {
|
|
2
|
+
readonly model?: string;
|
|
3
|
+
readonly n?: number;
|
|
4
|
+
readonly prompt: string;
|
|
5
|
+
readonly resolution?: "1k" | "2k";
|
|
6
|
+
readonly response_format?: "url" | "b64_json";
|
|
7
|
+
readonly size?: string;
|
|
8
|
+
}): Promise<Record<string, unknown>>;
|
|
9
|
+
export declare function xaiTts(args: {
|
|
10
|
+
readonly bit_rate?: number;
|
|
11
|
+
readonly codec?: string;
|
|
12
|
+
readonly format?: string;
|
|
13
|
+
readonly input: string;
|
|
14
|
+
readonly language?: string;
|
|
15
|
+
readonly sample_rate?: number;
|
|
16
|
+
readonly text_normalization?: boolean;
|
|
17
|
+
readonly voice?: string;
|
|
18
|
+
readonly voice_id?: string;
|
|
19
|
+
}): Promise<{
|
|
20
|
+
readonly bytes: Buffer;
|
|
21
|
+
readonly contentType: string;
|
|
22
|
+
}>;
|
|
23
|
+
export declare function xaiVideoGenerate(args: {
|
|
24
|
+
readonly aspect_ratio?: string;
|
|
25
|
+
readonly duration?: number;
|
|
26
|
+
readonly image_url?: string;
|
|
27
|
+
readonly model?: string;
|
|
28
|
+
readonly prompt: string;
|
|
29
|
+
readonly reference_image_urls?: readonly string[];
|
|
30
|
+
readonly resolution?: "480p" | "720p";
|
|
31
|
+
}, options?: {
|
|
32
|
+
readonly maxWaitMs?: number;
|
|
33
|
+
readonly pollIntervalMs?: number;
|
|
34
|
+
}): Promise<Record<string, unknown>>;
|
|
35
|
+
//# sourceMappingURL=media.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { StoredAuth, TokenPayload } from "./types.js";
|
|
2
|
+
type Discovery = {
|
|
3
|
+
readonly authorization_endpoint: string;
|
|
4
|
+
readonly device_authorization_endpoint?: string;
|
|
5
|
+
readonly token_endpoint: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function pkcePair(): {
|
|
8
|
+
readonly challenge: string;
|
|
9
|
+
readonly verifier: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function buildAuthorizeUrl(args: {
|
|
12
|
+
readonly authorizationEndpoint: string;
|
|
13
|
+
readonly challenge: string;
|
|
14
|
+
readonly nonce: string;
|
|
15
|
+
readonly redirectUri: string;
|
|
16
|
+
readonly state: string;
|
|
17
|
+
}): string;
|
|
18
|
+
export declare function discoverXaiOAuth(): Promise<Discovery>;
|
|
19
|
+
export declare function refreshAccessToken(refreshToken: string, tokenEndpoint: string): Promise<TokenPayload>;
|
|
20
|
+
export declare function exchangeCodeForToken(input: {
|
|
21
|
+
readonly code: string;
|
|
22
|
+
readonly redirectUri: string;
|
|
23
|
+
readonly tokenEndpoint: string;
|
|
24
|
+
readonly verifier: string;
|
|
25
|
+
}): Promise<StoredAuth>;
|
|
26
|
+
export declare function storedAuthFromToken(token: TokenPayload, tokenEndpoint: string): StoredAuth;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { OpenAiChatCompletionRequest, ReasoningEffort, XaiResponseResult } from "./types.js";
|
|
2
|
+
export declare function xaiResponses(input: {
|
|
3
|
+
readonly model?: string;
|
|
4
|
+
readonly prompt: string;
|
|
5
|
+
readonly reasoningEffort?: ReasoningEffort;
|
|
6
|
+
readonly timeoutMs?: number;
|
|
7
|
+
readonly tools?: readonly Record<string, unknown>[];
|
|
8
|
+
}): Promise<XaiResponseResult>;
|
|
9
|
+
export declare function xaiChatCompletions(request: OpenAiChatCompletionRequest): Promise<Record<string, unknown>>;
|
|
10
|
+
//# sourceMappingURL=responses.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { StoredAuth } from "./types.js";
|
|
2
|
+
export declare function defaultAuthPath(): string;
|
|
3
|
+
export declare function authPath(): string;
|
|
4
|
+
export declare function defaultGrokAuthPath(): string;
|
|
5
|
+
export declare function grokAuthPath(): string;
|
|
6
|
+
export declare function readStoredAuth(path?: string): StoredAuth | undefined;
|
|
7
|
+
export declare function readGrokStoredAuth(path?: string): StoredAuth | undefined;
|
|
8
|
+
export declare function writeStoredAuth(auth: StoredAuth, path?: string): void;
|
|
9
|
+
export declare function oauthExpiry(timestampSeconds?: number): number;
|
|
10
|
+
export declare function accessTokenIsExpiring(token: string | undefined, skewMs?: number): boolean;
|
|
11
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export type StoredAuth = {
|
|
2
|
+
readonly access: string;
|
|
3
|
+
readonly expires: number;
|
|
4
|
+
readonly provider: "grok-oauth" | "xai-oauth";
|
|
5
|
+
readonly refresh: string;
|
|
6
|
+
readonly tokenEndpoint: string;
|
|
7
|
+
readonly tokenType: string;
|
|
8
|
+
};
|
|
9
|
+
export type XaiCredentials = {
|
|
10
|
+
readonly apiKey: string;
|
|
11
|
+
readonly baseUrl: string;
|
|
12
|
+
readonly provider: "codex-model-provider" | "grok-oauth" | "xai-oauth" | "xai";
|
|
13
|
+
};
|
|
14
|
+
export type CredentialStatus = {
|
|
15
|
+
readonly success: true;
|
|
16
|
+
readonly auth_file: string;
|
|
17
|
+
readonly base_url: string;
|
|
18
|
+
readonly codex_config_file?: string;
|
|
19
|
+
readonly credential_source: XaiCredentials["provider"];
|
|
20
|
+
readonly oauth_file_present: boolean;
|
|
21
|
+
} | {
|
|
22
|
+
readonly success: false;
|
|
23
|
+
readonly auth_file: string;
|
|
24
|
+
readonly codex_config_file?: string;
|
|
25
|
+
readonly error: string;
|
|
26
|
+
readonly oauth_file_present: boolean;
|
|
27
|
+
};
|
|
28
|
+
export type ReasoningEffort = "low" | "medium" | "high";
|
|
29
|
+
export type XaiResponseResult = {
|
|
30
|
+
readonly citations: unknown;
|
|
31
|
+
readonly inline_citations: readonly Record<string, unknown>[];
|
|
32
|
+
readonly payload: Record<string, unknown>;
|
|
33
|
+
readonly text: string;
|
|
34
|
+
};
|
|
35
|
+
export type DeviceCodeResponse = {
|
|
36
|
+
readonly device_code: string;
|
|
37
|
+
readonly expires_in?: number;
|
|
38
|
+
readonly interval?: number;
|
|
39
|
+
readonly user_code: string;
|
|
40
|
+
readonly verification_uri: string;
|
|
41
|
+
readonly verification_uri_complete?: string;
|
|
42
|
+
};
|
|
43
|
+
export type TokenPayload = {
|
|
44
|
+
readonly access_token?: string;
|
|
45
|
+
readonly expires_in?: number;
|
|
46
|
+
readonly refresh_token?: string;
|
|
47
|
+
readonly token_type?: string;
|
|
48
|
+
};
|
|
49
|
+
export type OpenAiChatMessage = {
|
|
50
|
+
readonly content?: unknown;
|
|
51
|
+
readonly role: string;
|
|
52
|
+
};
|
|
53
|
+
export type OpenAiChatCompletionRequest = {
|
|
54
|
+
readonly messages?: readonly OpenAiChatMessage[];
|
|
55
|
+
readonly model?: string;
|
|
56
|
+
readonly stream?: boolean;
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=types.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "codex-xai-oauth",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Codex plugin exposing xAI/Grok OAuth and API-key tools through a local MCP server.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/mcp/server.js",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/islee23520/codex-xai-oauth.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/islee23520/codex-xai-oauth#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/islee23520/codex-xai-oauth/issues"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"codex-xai-oauth": "./dist/cli.js"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
20
|
+
"setup": "npm run build && node dist/cli.js setup",
|
|
21
|
+
"doctor": "npm run build && node dist/cli.js doctor",
|
|
22
|
+
"test": "tsx --test test/*.test.ts",
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"build": "npm run clean && npm run build:types && npm run build:bundle",
|
|
25
|
+
"build:types": "tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
26
|
+
"build:bundle": "esbuild src/mcp/server.ts --bundle --platform=node --format=esm --target=node20 --outfile=dist/mcp/server.js --sourcemap && esbuild src/cli.ts --bundle --platform=node --format=esm --target=node20 --outfile=dist/cli.js --sourcemap",
|
|
27
|
+
"lint": "biome check .",
|
|
28
|
+
"lint:fix": "biome check --write .",
|
|
29
|
+
"format": "biome format --write .",
|
|
30
|
+
"prepare": "npm run build",
|
|
31
|
+
"prepack": "npm run build"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"codex",
|
|
35
|
+
"mcp",
|
|
36
|
+
"xai",
|
|
37
|
+
"grok",
|
|
38
|
+
"oauth",
|
|
39
|
+
"image-generation"
|
|
40
|
+
],
|
|
41
|
+
"author": {
|
|
42
|
+
"name": "ilseoblee"
|
|
43
|
+
},
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
47
|
+
"commander": "^15.0.0",
|
|
48
|
+
"ky": "^2.0.2",
|
|
49
|
+
"zod": "^4.4.3"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@biomejs/biome": "2.4.16",
|
|
53
|
+
"@types/node": "^25.0.0",
|
|
54
|
+
"esbuild": "^0.27.0",
|
|
55
|
+
"tsx": "^4.21.0",
|
|
56
|
+
"typescript": "^5.9.3"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: xai-grok
|
|
3
|
+
description: Use xAI/Grok OAuth or API-key MCP tools for text generation, web search, X search, image generation, TTS, video generation, or credential status from Codex.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# xAI Grok
|
|
7
|
+
|
|
8
|
+
Use the bundled MCP tools when the user asks for xAI, Grok, Grok Imagine, xAI image generation, xAI web search, X search, TTS, video generation, or xAI credential status.
|
|
9
|
+
|
|
10
|
+
## Tools
|
|
11
|
+
|
|
12
|
+
- `xai_status`: check whether OAuth or `XAI_API_KEY` credentials are available. Never expose token material.
|
|
13
|
+
- `xai_login_instructions`: show local setup commands and the auth-file path.
|
|
14
|
+
- `xai_generate_text`: generate text with Grok through xAI Responses.
|
|
15
|
+
- `xai_web_search`: answer with xAI server-side web search.
|
|
16
|
+
- `xai_x_search`: answer with xAI server-side X search. Do not pass both allowed and excluded handles.
|
|
17
|
+
- `xai_image_generate`: generate images with xAI `/images/generations`.
|
|
18
|
+
- `xai_tts`: generate speech audio.
|
|
19
|
+
- `xai_video_generate`: generate video.
|
|
20
|
+
|
|
21
|
+
## Credential Rules
|
|
22
|
+
|
|
23
|
+
- Prefer existing OAuth credentials in `~/.config/codex-xai-oauth/auth.json`.
|
|
24
|
+
- If package OAuth credentials are absent, use the Grok CLI OIDC session in `~/.grok/auth.json`.
|
|
25
|
+
- `CODEX_XAI_OAUTH_AUTH_FILE` overrides the auth-file path.
|
|
26
|
+
- `CODEX_XAI_OAUTH_GROK_AUTH_FILE` overrides the Grok CLI auth-file path.
|
|
27
|
+
- `XAI_API_KEY` is the fallback credential.
|
|
28
|
+
- `XAI_BASE_URL` can override the API base URL.
|
|
29
|
+
- Do not print, quote, summarize, or store access tokens, refresh tokens, or API keys in chat.
|
|
30
|
+
|
|
31
|
+
## Setup
|
|
32
|
+
|
|
33
|
+
For OAuth device flow:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
codex-xai-oauth login --device
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
For API-key fallback:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
export XAI_API_KEY=xai-...
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
To check status:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
codex-xai-oauth status
|
|
49
|
+
```
|