@bigknoxy/exa-cli 0.1.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.
- package/LICENSE +21 -0
- package/README.md +250 -0
- package/dist/commands/code.d.ts +23 -0
- package/dist/commands/code.d.ts.map +1 -0
- package/dist/commands/code.js +55 -0
- package/dist/commands/code.js.map +1 -0
- package/dist/commands/company.d.ts +26 -0
- package/dist/commands/company.d.ts.map +1 -0
- package/dist/commands/company.js +58 -0
- package/dist/commands/company.js.map +1 -0
- package/dist/commands/completion.d.ts +13 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +423 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/config.d.ts +23 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +119 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/crawl.d.ts +23 -0
- package/dist/commands/crawl.d.ts.map +1 -0
- package/dist/commands/crawl.js +55 -0
- package/dist/commands/crawl.js.map +1 -0
- package/dist/commands/index.d.ts +10 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +10 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/people.d.ts +26 -0
- package/dist/commands/people.d.ts.map +1 -0
- package/dist/commands/people.js +58 -0
- package/dist/commands/people.js.map +1 -0
- package/dist/commands/research.d.ts +6 -0
- package/dist/commands/research.d.ts.map +1 -0
- package/dist/commands/research.js +191 -0
- package/dist/commands/research.js.map +1 -0
- package/dist/commands/search-advanced.d.ts +64 -0
- package/dist/commands/search-advanced.d.ts.map +1 -0
- package/dist/commands/search-advanced.js +137 -0
- package/dist/commands/search-advanced.js.map +1 -0
- package/dist/commands/search.d.ts +36 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +74 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +23 -0
- package/dist/lib/config.d.ts +29 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +62 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/mcp-client.d.ts +15 -0
- package/dist/lib/mcp-client.d.ts.map +1 -0
- package/dist/lib/mcp-client.js +103 -0
- package/dist/lib/mcp-client.js.map +1 -0
- package/dist/lib/output.d.ts +13 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +167 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.js +5 -0
- package/package.json +63 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search command - Wraps the MCP web_search_exa tool
|
|
3
|
+
*/
|
|
4
|
+
import { defineCommand } from 'citty';
|
|
5
|
+
import { consola } from 'consola';
|
|
6
|
+
import { getMcpClient } from '../lib/mcp-client.js';
|
|
7
|
+
import { formatOutput } from '../lib/output.js';
|
|
8
|
+
const VALID_TYPES = ['auto', 'fast'];
|
|
9
|
+
const VALID_LIVECRAWL = ['fallback', 'preferred'];
|
|
10
|
+
const VALID_FORMATS = ['text', 'json', 'markdown'];
|
|
11
|
+
export default defineCommand({
|
|
12
|
+
meta: {
|
|
13
|
+
name: 'search',
|
|
14
|
+
description: 'Search the web using Exa',
|
|
15
|
+
},
|
|
16
|
+
args: {
|
|
17
|
+
query: {
|
|
18
|
+
type: 'positional',
|
|
19
|
+
required: true,
|
|
20
|
+
description: 'Search query',
|
|
21
|
+
},
|
|
22
|
+
num: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
default: '8',
|
|
25
|
+
description: 'Number of results',
|
|
26
|
+
},
|
|
27
|
+
type: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
default: 'auto',
|
|
30
|
+
description: `Search type (${VALID_TYPES.join(', ')})`,
|
|
31
|
+
},
|
|
32
|
+
livecrawl: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
default: 'fallback',
|
|
35
|
+
description: `Live crawl mode (${VALID_LIVECRAWL.join(', ')})`,
|
|
36
|
+
},
|
|
37
|
+
format: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
default: 'text',
|
|
40
|
+
description: `Output format (${VALID_FORMATS.join(', ')})`,
|
|
41
|
+
},
|
|
42
|
+
'api-key': {
|
|
43
|
+
type: 'string',
|
|
44
|
+
description: 'Override API key',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
async run({ args }) {
|
|
48
|
+
const { query, num, type, livecrawl, format, 'api-key': apiKey } = args;
|
|
49
|
+
const numResults = parseInt(String(num), 10) || 8;
|
|
50
|
+
const searchType = VALID_TYPES.includes(type) ? type : 'auto';
|
|
51
|
+
const livecrawlMode = VALID_LIVECRAWL.includes(livecrawl) ? livecrawl : 'fallback';
|
|
52
|
+
const outputFormat = VALID_FORMATS.includes(format) ? format : 'text';
|
|
53
|
+
const client = getMcpClient();
|
|
54
|
+
try {
|
|
55
|
+
await client.connect(apiKey);
|
|
56
|
+
const result = await client.callTool('web_search_exa', {
|
|
57
|
+
query,
|
|
58
|
+
numResults,
|
|
59
|
+
type: searchType,
|
|
60
|
+
livecrawl: livecrawlMode,
|
|
61
|
+
});
|
|
62
|
+
const output = formatOutput(result, outputFormat);
|
|
63
|
+
console.log(output);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
consola.error('Search failed:', error instanceof Error ? error.message : 'Unknown error');
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
await client.close();
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { defineCommand, runMain } from 'citty';
|
|
3
|
+
import { search, searchAdvanced, code, crawl, company, people, config, research, completion } from './commands/index.js';
|
|
4
|
+
const main = defineCommand({
|
|
5
|
+
meta: {
|
|
6
|
+
name: 'exa',
|
|
7
|
+
version: '0.1.0',
|
|
8
|
+
description: 'CLI for Exa search API - wraps Exa MCP tools',
|
|
9
|
+
},
|
|
10
|
+
subCommands: {
|
|
11
|
+
search,
|
|
12
|
+
'search-advanced': searchAdvanced,
|
|
13
|
+
code,
|
|
14
|
+
crawl,
|
|
15
|
+
company,
|
|
16
|
+
people,
|
|
17
|
+
config,
|
|
18
|
+
research,
|
|
19
|
+
completion,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
runMain(main);
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path to the config file (~/.exarc)
|
|
3
|
+
*/
|
|
4
|
+
export declare const CONFIG_FILE_PATH: string;
|
|
5
|
+
/**
|
|
6
|
+
* Shape of the configuration object
|
|
7
|
+
*/
|
|
8
|
+
export interface Config {
|
|
9
|
+
apiKey?: string;
|
|
10
|
+
output?: string;
|
|
11
|
+
defaultNum?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Load configuration from ~/.exarc
|
|
15
|
+
* @returns The loaded configuration or default config if file doesn't exist
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadConfig(): Config;
|
|
18
|
+
/**
|
|
19
|
+
* Save configuration to ~/.exarc
|
|
20
|
+
* @param config - The configuration to save
|
|
21
|
+
*/
|
|
22
|
+
export declare function saveConfig(config: Config): void;
|
|
23
|
+
/**
|
|
24
|
+
* Update specific config values while preserving others
|
|
25
|
+
* @param updates - Partial config to merge with existing config
|
|
26
|
+
* @returns The updated configuration
|
|
27
|
+
*/
|
|
28
|
+
export declare function updateConfig(updates: Partial<Config>): Config;
|
|
29
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAA4B,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAUD;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAmBnC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAQ/C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAK7D"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { homedir } from "os";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
4
|
+
/**
|
|
5
|
+
* Path to the config file (~/.exarc)
|
|
6
|
+
*/
|
|
7
|
+
export const CONFIG_FILE_PATH = join(homedir(), ".exarc");
|
|
8
|
+
/**
|
|
9
|
+
* Default configuration values
|
|
10
|
+
*/
|
|
11
|
+
const DEFAULT_CONFIG = {
|
|
12
|
+
output: "json",
|
|
13
|
+
defaultNum: 10,
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Load configuration from ~/.exarc
|
|
17
|
+
* @returns The loaded configuration or default config if file doesn't exist
|
|
18
|
+
*/
|
|
19
|
+
export function loadConfig() {
|
|
20
|
+
try {
|
|
21
|
+
if (!existsSync(CONFIG_FILE_PATH)) {
|
|
22
|
+
return { ...DEFAULT_CONFIG };
|
|
23
|
+
}
|
|
24
|
+
const content = readFileSync(CONFIG_FILE_PATH, "utf-8");
|
|
25
|
+
const config = JSON.parse(content);
|
|
26
|
+
// Merge with defaults
|
|
27
|
+
return {
|
|
28
|
+
...DEFAULT_CONFIG,
|
|
29
|
+
...config,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
console.warn("Failed to load config, using defaults:", error instanceof Error ? error.message : "Unknown error");
|
|
34
|
+
return { ...DEFAULT_CONFIG };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Save configuration to ~/.exarc
|
|
39
|
+
* @param config - The configuration to save
|
|
40
|
+
*/
|
|
41
|
+
export function saveConfig(config) {
|
|
42
|
+
try {
|
|
43
|
+
const content = JSON.stringify(config, null, 2);
|
|
44
|
+
writeFileSync(CONFIG_FILE_PATH, content, "utf-8");
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
48
|
+
throw new Error(`Failed to save config: ${errorMessage}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Update specific config values while preserving others
|
|
53
|
+
* @param updates - Partial config to merge with existing config
|
|
54
|
+
* @returns The updated configuration
|
|
55
|
+
*/
|
|
56
|
+
export function updateConfig(updates) {
|
|
57
|
+
const currentConfig = loadConfig();
|
|
58
|
+
const updatedConfig = { ...currentConfig, ...updates };
|
|
59
|
+
saveConfig(updatedConfig);
|
|
60
|
+
return updatedConfig;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AAW1D;;GAEG;AACH,MAAM,cAAc,GAAW;IAC7B,MAAM,EAAE,MAAM;IACd,UAAU,EAAE,EAAE;CACf,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;QAC/B,CAAC;QAED,MAAM,OAAO,GAAG,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAoB,CAAC;QAEtD,sBAAsB;QACtB,OAAO;YACL,GAAG,cAAc;YACjB,GAAG,MAAM;SACV,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,wCAAwC,EACnD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QAC5D,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAChD,aAAa,CAAC,gBAAgB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,0BAA0B,YAAY,EAAE,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,OAAwB;IACnD,MAAM,aAAa,GAAG,UAAU,EAAE,CAAC;IACnC,MAAM,aAAa,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACvD,UAAU,CAAC,aAAa,CAAC,CAAC;IAC1B,OAAO,aAAa,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CallToolResult, ListToolsResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export declare class ExaMcpClient {
|
|
3
|
+
private client;
|
|
4
|
+
private transport;
|
|
5
|
+
private connected;
|
|
6
|
+
connect(apiKey?: string): Promise<void>;
|
|
7
|
+
listTools(): Promise<ListToolsResult>;
|
|
8
|
+
callTool(name: string, args: Record<string, unknown>): Promise<CallToolResult>;
|
|
9
|
+
isConnected(): boolean;
|
|
10
|
+
close(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export declare function getMcpClient(): ExaMcpClient;
|
|
13
|
+
export declare function createMcpClient(): ExaMcpClient;
|
|
14
|
+
export type { CallToolResult, ListToolsResult };
|
|
15
|
+
//# sourceMappingURL=mcp-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../../src/lib/mcp-client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAA;AAezF,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,SAAS,CAAkE;IACnF,OAAO,CAAC,SAAS,CAAiB;IAE5B,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA+CvC,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;IAQrC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC;IAQpF,WAAW,IAAI,OAAO;IAIhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAY7B;AAID,wBAAgB,YAAY,IAAI,YAAY,CAK3C;AAED,wBAAgB,eAAe,IAAI,YAAY,CAE9C;AAED,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,CAAA"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
3
|
+
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
4
|
+
const MCP_SERVER_URL = "https://mcp.exa.ai/mcp";
|
|
5
|
+
const ALL_TOOLS = [
|
|
6
|
+
"web_search_exa",
|
|
7
|
+
"web_search_advanced_exa",
|
|
8
|
+
"get_code_context_exa",
|
|
9
|
+
"crawling_exa",
|
|
10
|
+
"company_research_exa",
|
|
11
|
+
"people_search_exa",
|
|
12
|
+
"deep_researcher_start",
|
|
13
|
+
"deep_researcher_check",
|
|
14
|
+
].join(",");
|
|
15
|
+
export class ExaMcpClient {
|
|
16
|
+
client = null;
|
|
17
|
+
transport = null;
|
|
18
|
+
connected = false;
|
|
19
|
+
async connect(apiKey) {
|
|
20
|
+
if (this.connected && this.client) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const resolvedApiKey = apiKey || process.env.EXA_API_KEY;
|
|
24
|
+
try {
|
|
25
|
+
const params = new URLSearchParams();
|
|
26
|
+
params.set("tools", ALL_TOOLS);
|
|
27
|
+
if (resolvedApiKey) {
|
|
28
|
+
params.set("exaApiKey", resolvedApiKey);
|
|
29
|
+
}
|
|
30
|
+
const url = `${MCP_SERVER_URL}?${params.toString()}`;
|
|
31
|
+
this.client = new Client({
|
|
32
|
+
name: "exa-cli",
|
|
33
|
+
version: "1.0.0",
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
this.transport = new StreamableHTTPClientTransport(new URL(url));
|
|
37
|
+
await this.client.connect(this.transport);
|
|
38
|
+
this.connected = true;
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
catch (httpError) {
|
|
42
|
+
console.warn("StreamableHTTP failed, trying SSE:", httpError instanceof Error ? httpError.message : "Unknown");
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
this.transport = new SSEClientTransport(new URL(url));
|
|
46
|
+
await this.client.connect(this.transport);
|
|
47
|
+
this.connected = true;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
catch (sseError) {
|
|
51
|
+
console.warn("SSE transport failed:", sseError instanceof Error ? sseError.message : "Unknown");
|
|
52
|
+
}
|
|
53
|
+
throw new Error("Failed to connect with both transport types");
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
this.connected = false;
|
|
57
|
+
this.client = null;
|
|
58
|
+
this.transport = null;
|
|
59
|
+
throw new Error(`Failed to connect to Exa MCP: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async listTools() {
|
|
63
|
+
if (!this.client || !this.connected) {
|
|
64
|
+
throw new Error("Not connected. Call connect() first.");
|
|
65
|
+
}
|
|
66
|
+
const result = await this.client.listTools();
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
async callTool(name, args) {
|
|
70
|
+
if (!this.client || !this.connected) {
|
|
71
|
+
throw new Error("Not connected. Call connect() first.");
|
|
72
|
+
}
|
|
73
|
+
const result = await this.client.callTool({ name, arguments: args });
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
isConnected() {
|
|
77
|
+
return this.connected;
|
|
78
|
+
}
|
|
79
|
+
async close() {
|
|
80
|
+
if (this.client && this.connected) {
|
|
81
|
+
try {
|
|
82
|
+
await this.client.close();
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Ignore close errors
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
this.client = null;
|
|
89
|
+
this.transport = null;
|
|
90
|
+
this.connected = false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
let mcpClientInstance = null;
|
|
94
|
+
export function getMcpClient() {
|
|
95
|
+
if (!mcpClientInstance) {
|
|
96
|
+
mcpClientInstance = new ExaMcpClient();
|
|
97
|
+
}
|
|
98
|
+
return mcpClientInstance;
|
|
99
|
+
}
|
|
100
|
+
export function createMcpClient() {
|
|
101
|
+
return new ExaMcpClient();
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=mcp-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../src/lib/mcp-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { OutputFormat } from '../types.js';
|
|
2
|
+
interface ParsedResult {
|
|
3
|
+
title: string;
|
|
4
|
+
url: string;
|
|
5
|
+
publishedDate?: string;
|
|
6
|
+
author?: string;
|
|
7
|
+
text: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function formatOutput(data: unknown, format: OutputFormat): string;
|
|
10
|
+
export declare function formatSearchResults(results: ParsedResult[], format: OutputFormat): string;
|
|
11
|
+
export declare function formatCrawlResult(data: unknown, format: OutputFormat): string;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb;AA4ED,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAiBxE;AAmDD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CA+BzF;AAQD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAsB7E"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
function extractTextContent(data) {
|
|
3
|
+
if (data &&
|
|
4
|
+
typeof data === 'object' &&
|
|
5
|
+
'content' in data &&
|
|
6
|
+
Array.isArray(data.content)) {
|
|
7
|
+
const content = data.content;
|
|
8
|
+
const textItem = content.find((item) => item.type === 'text');
|
|
9
|
+
if (textItem?.text) {
|
|
10
|
+
return textItem.text;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
if (typeof data === 'string') {
|
|
14
|
+
return data;
|
|
15
|
+
}
|
|
16
|
+
return JSON.stringify(data, null, 2);
|
|
17
|
+
}
|
|
18
|
+
function parseExaFormat(text) {
|
|
19
|
+
const results = [];
|
|
20
|
+
const blocks = text.split(/(?=^Title:)/m).filter(b => b.trim());
|
|
21
|
+
for (const block of blocks) {
|
|
22
|
+
const titleMatch = block.match(/^Title:\s*(.+)$/m);
|
|
23
|
+
const urlMatch = block.match(/^URL:\s*(.+)$/m);
|
|
24
|
+
const dateMatch = block.match(/^Published Date:\s*(.+)$/m);
|
|
25
|
+
const authorMatch = block.match(/^Author:\s*(.+)$/m);
|
|
26
|
+
const textMatch = block.match(/^Text:\s*([\s\S]+?)(?=^Title:|$)/m);
|
|
27
|
+
if (titleMatch || urlMatch) {
|
|
28
|
+
results.push({
|
|
29
|
+
title: titleMatch?.[1]?.trim() || '',
|
|
30
|
+
url: urlMatch?.[1]?.trim() || '',
|
|
31
|
+
publishedDate: dateMatch?.[1]?.trim(),
|
|
32
|
+
author: authorMatch?.[1]?.trim(),
|
|
33
|
+
text: textMatch?.[1]?.trim() || block.trim(),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return results;
|
|
38
|
+
}
|
|
39
|
+
function tryParseJson(text) {
|
|
40
|
+
try {
|
|
41
|
+
return JSON.parse(text);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function formatOutput(data, format) {
|
|
48
|
+
const text = extractTextContent(data);
|
|
49
|
+
const parsed = parseExaFormat(text);
|
|
50
|
+
if (parsed.length > 0) {
|
|
51
|
+
return formatSearchResults(parsed, format);
|
|
52
|
+
}
|
|
53
|
+
const jsonData = tryParseJson(text);
|
|
54
|
+
if (jsonData?.results?.[0]?.entities) {
|
|
55
|
+
return formatCompanyResult(jsonData, format);
|
|
56
|
+
}
|
|
57
|
+
if (jsonData?.results) {
|
|
58
|
+
return formatApiResults(jsonData.results, format);
|
|
59
|
+
}
|
|
60
|
+
return text;
|
|
61
|
+
}
|
|
62
|
+
function formatCompanyResult(data, format) {
|
|
63
|
+
const result = data.results?.[0];
|
|
64
|
+
if (!result)
|
|
65
|
+
return 'No results found.';
|
|
66
|
+
const entity = result.entities?.[0]?.properties;
|
|
67
|
+
const name = entity?.name || result.title || 'Unknown Company';
|
|
68
|
+
const url = result.url || '';
|
|
69
|
+
const description = entity?.description || '';
|
|
70
|
+
const employees = entity?.workforce?.total;
|
|
71
|
+
const headquarters = entity?.headquarters;
|
|
72
|
+
const revenue = entity?.financials?.revenueAnnual;
|
|
73
|
+
const funding = entity?.financials?.fundingTotal;
|
|
74
|
+
if (format === 'json') {
|
|
75
|
+
return JSON.stringify(data, null, 2);
|
|
76
|
+
}
|
|
77
|
+
if (format === 'markdown') {
|
|
78
|
+
let md = `# ${name}\n\n`;
|
|
79
|
+
if (url)
|
|
80
|
+
md += `**URL:** ${url}\n\n`;
|
|
81
|
+
if (description)
|
|
82
|
+
md += `${description}\n\n`;
|
|
83
|
+
if (employees)
|
|
84
|
+
md += `**Employees:** ${employees.toLocaleString()}\n\n`;
|
|
85
|
+
if (headquarters)
|
|
86
|
+
md += `**HQ:** ${headquarters.city || ''}, ${headquarters.country || ''}\n\n`;
|
|
87
|
+
if (revenue)
|
|
88
|
+
md += `**Revenue:** $${(revenue / 1e9).toFixed(1)}B\n\n`;
|
|
89
|
+
if (funding)
|
|
90
|
+
md += `**Total Funding:** $${(funding / 1e9).toFixed(1)}B\n\n`;
|
|
91
|
+
return md;
|
|
92
|
+
}
|
|
93
|
+
let output = `${chalk.bold.cyan(name)}\n`;
|
|
94
|
+
if (url)
|
|
95
|
+
output += `${chalk.dim.underline(url)}\n`;
|
|
96
|
+
output += '\n';
|
|
97
|
+
if (description)
|
|
98
|
+
output += `${chalk.dim(description.slice(0, 300))}${description.length > 300 ? '...' : ''}\n\n`;
|
|
99
|
+
if (employees)
|
|
100
|
+
output += `${chalk.bold('Employees:')} ${employees.toLocaleString()}\n`;
|
|
101
|
+
if (headquarters)
|
|
102
|
+
output += `${chalk.bold('HQ:')} ${headquarters.city || ''}, ${headquarters.country || ''}\n`;
|
|
103
|
+
if (revenue)
|
|
104
|
+
output += `${chalk.bold('Revenue:')} $${(revenue / 1e9).toFixed(1)}B\n`;
|
|
105
|
+
if (funding)
|
|
106
|
+
output += `${chalk.bold('Funding:')} $${(funding / 1e9).toFixed(1)}B\n`;
|
|
107
|
+
return output;
|
|
108
|
+
}
|
|
109
|
+
function formatApiResults(results, format) {
|
|
110
|
+
const parsed = results.map(r => ({
|
|
111
|
+
title: r.title || '',
|
|
112
|
+
url: r.url || '',
|
|
113
|
+
text: r.text || '',
|
|
114
|
+
}));
|
|
115
|
+
return formatSearchResults(parsed, format);
|
|
116
|
+
}
|
|
117
|
+
export function formatSearchResults(results, format) {
|
|
118
|
+
if (results.length === 0) {
|
|
119
|
+
return 'No results found.';
|
|
120
|
+
}
|
|
121
|
+
const output = results.map((result, i) => {
|
|
122
|
+
const num = chalk.cyan(`${i + 1}.`);
|
|
123
|
+
const title = chalk.bold(result.title || 'Untitled');
|
|
124
|
+
const url = chalk.dim.underline(result.url);
|
|
125
|
+
const date = result.publishedDate ? chalk.dim(` (${result.publishedDate.split('T')[0]})`) : '';
|
|
126
|
+
const snippet = truncateText(result.text, 200);
|
|
127
|
+
if (format === 'markdown') {
|
|
128
|
+
const mdLink = result.url ? `[${result.title}](${result.url})` : result.title;
|
|
129
|
+
return `${i + 1}. ${mdLink}${date}\n ${snippet}`;
|
|
130
|
+
}
|
|
131
|
+
if (format === 'json') {
|
|
132
|
+
return JSON.stringify({
|
|
133
|
+
title: result.title,
|
|
134
|
+
url: result.url,
|
|
135
|
+
publishedDate: result.publishedDate,
|
|
136
|
+
text: snippet,
|
|
137
|
+
}, null, 2);
|
|
138
|
+
}
|
|
139
|
+
return `${num} ${title}${date}\n ${url}\n ${chalk.dim(snippet)}`;
|
|
140
|
+
});
|
|
141
|
+
return output.join('\n\n');
|
|
142
|
+
}
|
|
143
|
+
function truncateText(text, maxLength) {
|
|
144
|
+
const cleaned = text.replace(/\s+/g, ' ').trim();
|
|
145
|
+
if (cleaned.length <= maxLength)
|
|
146
|
+
return cleaned;
|
|
147
|
+
return cleaned.slice(0, maxLength).trim() + '...';
|
|
148
|
+
}
|
|
149
|
+
export function formatCrawlResult(data, format) {
|
|
150
|
+
const text = extractTextContent(data);
|
|
151
|
+
if (format === 'json') {
|
|
152
|
+
return text;
|
|
153
|
+
}
|
|
154
|
+
const parsed = parseExaFormat(text);
|
|
155
|
+
if (parsed.length > 0) {
|
|
156
|
+
const result = parsed[0];
|
|
157
|
+
const title = chalk.bold(result.title);
|
|
158
|
+
const url = chalk.dim.underline(result.url);
|
|
159
|
+
const content = truncateText(result.text, 1000);
|
|
160
|
+
if (format === 'markdown') {
|
|
161
|
+
return `## ${result.title}\n\n${result.url}\n\n${content}`;
|
|
162
|
+
}
|
|
163
|
+
return `${title}\n${url}\n\n${content}`;
|
|
164
|
+
}
|
|
165
|
+
return truncateText(text, 1000);
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared TypeScript types for Exa CLI
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Output format for search results
|
|
6
|
+
*/
|
|
7
|
+
export type OutputFormat = 'text' | 'json' | 'markdown';
|
|
8
|
+
/**
|
|
9
|
+
* Configuration options for Exa API
|
|
10
|
+
*/
|
|
11
|
+
export interface ExaConfig {
|
|
12
|
+
/** Exa API key */
|
|
13
|
+
apiKey: string;
|
|
14
|
+
/** Output format for results */
|
|
15
|
+
output: OutputFormat;
|
|
16
|
+
/** Default number of results to return */
|
|
17
|
+
defaultNum: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Search result from Exa API
|
|
21
|
+
*/
|
|
22
|
+
export interface SearchResult {
|
|
23
|
+
/** Unique identifier for the result */
|
|
24
|
+
id: string;
|
|
25
|
+
/** Title of the result */
|
|
26
|
+
title: string;
|
|
27
|
+
/** URL of the result */
|
|
28
|
+
url: string;
|
|
29
|
+
/** Text content/description */
|
|
30
|
+
text: string;
|
|
31
|
+
/** Published date (if available) */
|
|
32
|
+
publishedDate?: string;
|
|
33
|
+
/** Author (if available) */
|
|
34
|
+
author?: string;
|
|
35
|
+
/** Score/relevance (0-1) */
|
|
36
|
+
score?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Search request options
|
|
40
|
+
*/
|
|
41
|
+
export interface SearchOptions {
|
|
42
|
+
/** Search query string */
|
|
43
|
+
query: string;
|
|
44
|
+
/** Number of results to return */
|
|
45
|
+
numResults?: number;
|
|
46
|
+
/** Output format */
|
|
47
|
+
output?: OutputFormat;
|
|
48
|
+
/** Include highlights in results */
|
|
49
|
+
highlights?: boolean;
|
|
50
|
+
/** Domain filters */
|
|
51
|
+
domains?: string[];
|
|
52
|
+
/** Exclude domains */
|
|
53
|
+
excludeDomains?: string[];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* MCP tool definition for Exa search
|
|
57
|
+
*/
|
|
58
|
+
export interface ExaTool {
|
|
59
|
+
name: string;
|
|
60
|
+
description: string;
|
|
61
|
+
inputSchema: {
|
|
62
|
+
type: 'object';
|
|
63
|
+
properties: {
|
|
64
|
+
query: {
|
|
65
|
+
type: 'string';
|
|
66
|
+
description: string;
|
|
67
|
+
};
|
|
68
|
+
numResults?: {
|
|
69
|
+
type: 'number';
|
|
70
|
+
description: string;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
required: string[];
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=types.d.ts.map
|