mirror of
https://github.com/hansjone/dsh-search-mcp.git
synced 2026-10-08 22:20:47 +08:00
Based on gxpppp/dsh-search-mcp; includes DSH web settings fixes, Clash fake-IP URL policy, and Bailian default server patch. Co-authored-by: Cursor <cursoragent@cursor.com>
137 lines
4.2 KiB
JavaScript
137 lines
4.2 KiB
JavaScript
/**
|
|
* Search-MCP provider catalog.
|
|
*
|
|
* Known providers are intentionally connection-opaque to Settings clients: the
|
|
* host owns their endpoint, transport, authentication contract and tool name.
|
|
* `custom` is the only kind whose connection details come from the user.
|
|
*/
|
|
export const SEARCH_MCP_CATALOG = {
|
|
tavily: {
|
|
transport: 'http',
|
|
url: 'https://mcp.tavily.com/mcp/',
|
|
authStyle: 'query',
|
|
authParam: 'tavilyApiKey',
|
|
toolName: 'tavily_search',
|
|
countArg: 'max_results',
|
|
minResults: 5,
|
|
maxResultsLimit: 20,
|
|
apiKeyEnv: 'TAVILY_API_KEY',
|
|
needsKey: true,
|
|
},
|
|
brave: {
|
|
transport: 'stdio',
|
|
command: 'npx',
|
|
args: ['-y', '@brave/brave-search-mcp-server@2.1.3'],
|
|
authStyle: 'env',
|
|
authParam: 'BRAVE_API_KEY',
|
|
toolName: 'brave_web_search',
|
|
countArg: 'count',
|
|
minResults: 1,
|
|
maxResultsLimit: 20,
|
|
apiKeyEnv: 'BRAVE_API_KEY',
|
|
needsKey: true,
|
|
},
|
|
exa: {
|
|
transport: 'http',
|
|
url: 'https://mcp.exa.ai/mcp',
|
|
authStyle: 'header',
|
|
authParam: 'x-api-key',
|
|
toolName: 'web_search_exa',
|
|
countArg: 'numResults',
|
|
apiKeyEnv: 'EXA_API_KEY',
|
|
needsKey: true,
|
|
},
|
|
perplexity: {
|
|
transport: 'http',
|
|
url: 'https://api.perplexity.ai/mcp',
|
|
authStyle: 'header',
|
|
authParam: 'Authorization',
|
|
authPrefix: 'Bearer ',
|
|
toolName: 'perplexity_search',
|
|
countArg: 'max_results',
|
|
minResults: 1,
|
|
maxResultsLimit: 20,
|
|
apiKeyEnv: 'PERPLEXITY_API_KEY',
|
|
needsKey: true,
|
|
},
|
|
duckduckgo: {
|
|
transport: 'stdio',
|
|
command: 'npx',
|
|
args: ['-y', 'duckduckgo-mcp-server@0.1.2'],
|
|
authStyle: 'env',
|
|
authParam: '',
|
|
toolName: 'duckduckgo_web_search',
|
|
countArg: 'count',
|
|
minResults: 1,
|
|
maxResultsLimit: 20,
|
|
needsKey: false,
|
|
},
|
|
custom: {
|
|
transport: 'http',
|
|
url: '',
|
|
authStyle: 'query',
|
|
authParam: '',
|
|
authPrefix: '',
|
|
toolName: '',
|
|
countArg: '',
|
|
needsKey: false,
|
|
},
|
|
};
|
|
|
|
/** The provider ids offered in the settings UI. */
|
|
export const KNOWN_KINDS = Object.keys(SEARCH_MCP_CATALOG);
|
|
|
|
export function clampSearchResults(server, value) {
|
|
const minimum = server.minResults ?? 1;
|
|
const maximum = server.maxResultsLimit ?? value;
|
|
return Math.min(maximum, Math.max(minimum, value));
|
|
}
|
|
|
|
/** Resolve a stored entry without allowing known-provider connection overrides. */
|
|
export function resolveServer(server) {
|
|
const kind = typeof server?.kind === 'string' && Object.hasOwn(SEARCH_MCP_CATALOG, server.kind)
|
|
? server.kind
|
|
: 'custom';
|
|
const preset = SEARCH_MCP_CATALOG[kind];
|
|
if (kind !== 'custom') {
|
|
return {
|
|
id: typeof server.id === 'string' ? server.id : '',
|
|
kind,
|
|
apiKey: typeof server.apiKey === 'string' ? server.apiKey : undefined,
|
|
apiKeyEnv: typeof server.apiKeyEnv === 'string' ? server.apiKeyEnv : '',
|
|
maxResults: server.maxResults,
|
|
transport: preset.transport,
|
|
url: preset.url ?? '',
|
|
command: preset.command ?? '',
|
|
args: [...(preset.args ?? [])],
|
|
authStyle: preset.authStyle ?? '',
|
|
authParam: preset.authParam ?? '',
|
|
authPrefix: preset.authPrefix ?? '',
|
|
toolName: preset.toolName ?? '',
|
|
countArg: preset.countArg ?? '',
|
|
minResults: preset.minResults,
|
|
maxResultsLimit: preset.maxResultsLimit,
|
|
needsKey: preset.needsKey ?? false,
|
|
};
|
|
}
|
|
|
|
return {
|
|
id: typeof server.id === 'string' ? server.id : '',
|
|
kind: 'custom',
|
|
apiKey: typeof server.apiKey === 'string' ? server.apiKey : undefined,
|
|
apiKeyEnv: typeof server.apiKeyEnv === 'string' ? server.apiKeyEnv : '',
|
|
maxResults: server.maxResults,
|
|
transport: server.transport || preset.transport || 'http',
|
|
url: server.url || preset.url || '',
|
|
command: server.command || preset.command || '',
|
|
args: Array.isArray(server.args) ? [...server.args] : [...(preset.args ?? [])],
|
|
authStyle: server.authStyle || preset.authStyle || '',
|
|
authParam: server.authParam || preset.authParam || '',
|
|
authPrefix: server.authPrefix || preset.authPrefix || '',
|
|
toolName: server.toolName || preset.toolName || '',
|
|
countArg: preset.countArg || '',
|
|
minResults: preset.minResults,
|
|
maxResultsLimit: preset.maxResultsLimit,
|
|
needsKey: preset.needsKey ?? false,
|
|
};
|
|
}
|