evalstate's picture
download
raw
40.4 kB
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { createRequire } from 'module';
import { performance } from 'node:perf_hooks';
import { whoAmI } from '@huggingface/hub';
import { SpaceSearchTool, formatSearchResults, SEMANTIC_SEARCH_TOOL_CONFIG, MODEL_SEARCH_TOOL_CONFIG, RepoSearchTool, REPO_SEARCH_TOOL_CONFIG, CreateRepoTool, formatCreateRepoResult, ModelDetailTool, MODEL_DETAIL_TOOL_CONFIG, MODEL_DETAIL_PROMPT_CONFIG, PaperSearchTool, PAPER_SEARCH_TOOL_CONFIG, DATASET_SEARCH_TOOL_CONFIG, DatasetDetailTool, DATASET_DETAIL_TOOL_CONFIG, DATASET_DETAIL_PROMPT_CONFIG, HUB_REPO_DETAILS_TOOL_CONFIG, HubInspectTool, DuplicateSpaceTool, formatDuplicateResult, SpaceInfoTool, formatSpaceInfoResult, SpaceFilesTool, UseSpaceTool, USE_SPACE_TOOL_CONFIG, formatUseSpaceResult, UserSummaryPrompt, USER_SUMMARY_PROMPT_CONFIG, PaperSummaryPrompt, PAPER_SUMMARY_PROMPT_CONFIG, CONFIG_GUIDANCE, TOOL_ID_GROUPS, DOCS_SEMANTIC_SEARCH_CONFIG, DocSearchTool, DOC_FETCH_CONFIG, DocFetchTool, HF_JOBS_TOOL_CONFIG, HfJobsTool, getDynamicSpaceToolConfig, SpaceTool, VIEW_PARAMETERS, } from '@llmindset/hf-mcp';
import { logger } from './utils/logger.js';
import { logSearchQuery, logPromptQuery, logGradioEvent } from './utils/query-logger.js';
import { DEFAULT_SPACE_TOOLS } from '../shared/settings.js';
import { extractAuthBouquetAndMix } from './utils/auth-utils.js';
import { AUTHENTICATED_BUILTIN_TOOL_IDS, ToolSelectionStrategy, } from './utils/tool-selection-strategy.js';
import { hasReadmeFlag } from '../shared/behavior-flags.js';
import { registerCapabilities } from './utils/capability-utils.js';
import { createGradioWidgetResourceConfig } from './resources/gradio-widget-resource.js';
import { applyResultPostProcessing } from './utils/gradio-tool-caller.js';
import { registerSkillResources } from './skills/skill-resources.js';
import { isClientDenied } from '../shared/client-denylist.js';
import { getSkillCatalog } from './skills/skill-catalog-cache.js';
export const BOUQUET_FALLBACK = {
builtInTools: [...TOOL_ID_GROUPS.hf_api],
spaceTools: DEFAULT_SPACE_TOOLS,
};
export const createServerFactory = (_webServerInstance, sharedApiClient) => {
const require = createRequire(import.meta.url);
const { version } = require('../../package.json');
return async (headers, userSettings, skipGradio, sessionInfo) => {
logger.debug({ skipGradio, sessionInfo }, '=== CREATING NEW MCP SERVER INSTANCE ===');
const { hfToken } = extractAuthBouquetAndMix(headers);
const toolSelectionStrategy = new ToolSelectionStrategy(sharedApiClient);
let userInfo = 'The Hugging Face tools are being used anonymously and rate limits apply. ' +
'Direct the User to set their HF_TOKEN (instructions at https://hf.co/settings/mcp/), or ' +
'create an account at https://hf.co/join for higher limits.';
let username;
let userDetails;
if (hfToken) {
try {
userDetails = await whoAmI({ credentials: { accessToken: hfToken } });
username = userDetails.name;
userInfo = `Hugging Face tools are being used by authenticated user '${userDetails.name}'`;
}
catch (error) {
logger.warn({ error: error.message }, `Failed to authenticate with Hugging Face API`);
}
}
const getLoggingOptions = () => {
const options = {
clientSessionId: sessionInfo?.clientSessionId,
isAuthenticated: sessionInfo?.isAuthenticated ?? !!hfToken,
clientName: sessionInfo?.clientInfo?.name,
clientVersion: sessionInfo?.clientInfo?.version,
};
logger.debug({ sessionInfo, options }, 'Query logging options:');
return options;
};
const runWithQueryLogging = async (logFn, config, work) => {
const start = performance.now();
try {
const result = await work();
const durationMs = Math.round(performance.now() - start);
const successOptions = config.successOptions?.(result) ?? {};
const { success: successOverride, ...restSuccessOptions } = successOptions;
const resultHasError = typeof result === 'object' &&
result !== null &&
'isError' in result &&
Boolean(result.isError);
const successFlag = successOverride ?? !resultHasError;
logFn(config.methodName, config.query, config.parameters, {
...config.baseOptions,
...restSuccessOptions,
durationMs,
success: successFlag,
});
return result;
}
catch (error) {
const durationMs = Math.round(performance.now() - start);
logFn(config.methodName, config.query, config.parameters, {
...config.baseOptions,
durationMs,
success: false,
error,
});
throw error;
}
};
const skillCatalog = await getSkillCatalog();
const clientDenied = isClientDenied(sessionInfo?.clientInfo?.name, headers?.['user-agent']);
const hasSkills = !!skillCatalog?.skills.length && !clientDenied;
const server = new McpServer({
name: '@huggingface/mcp-services',
version: version,
title: 'Hugging Face',
websiteUrl: 'https://huggingface.co/mcp',
icons: [
{
src: 'https://huggingface.co/favicon.ico',
},
],
}, {
instructions: "You have tools for using the Hugging Face Hub. arXiv paper id's are often " +
'used as references between datasets, models and papers. There are over 100 tags in use, ' +
"common tags include 'Text Generation', 'Transformers', 'Image Classification' and so on.\n" +
userInfo,
});
const toolSelectionContext = {
headers,
userSettings,
hfToken,
};
const toolSelection = await toolSelectionStrategy.selectTools(toolSelectionContext);
const rawNoImageHeader = headers?.['x-mcp-no-image-content'];
const noImageContentHeaderEnabled = typeof rawNoImageHeader === 'string' && rawNoImageHeader.trim().toLowerCase() === 'true';
const toolInstances = {};
const whoDescription = userDetails
? `Hugging Face tools are being used by authenticated user '${username}'`
: 'Hugging Face tools are being used anonymously and may be rate limited. Call this tool for instructions on joining and authenticating.';
const response = userDetails ? `You are authenticated as ${username ?? 'unknown'}.` : CONFIG_GUIDANCE;
server.tool('hf_whoami', whoDescription, {}, { readOnlyHint: true, openWorldHint: false, title: 'Hugging Face User Info' }, () => {
return { content: [{ type: 'text', text: response }] };
});
if (process.env.AUTHENTICATE_TOOL === 'true') {
server.tool('Authenticate', 'Authenticate with Hugging Face', {}, { title: 'Hugging Face Authentication' }, () => {
return { content: [{ type: 'text', text: 'You have successfully authenticated' }] };
});
}
server.prompt(USER_SUMMARY_PROMPT_CONFIG.name, USER_SUMMARY_PROMPT_CONFIG.description, USER_SUMMARY_PROMPT_CONFIG.schema.shape, async (params) => {
const summaryText = await runWithQueryLogging(logPromptQuery, {
methodName: USER_SUMMARY_PROMPT_CONFIG.name,
query: params.user_id,
parameters: { user_id: params.user_id },
baseOptions: getLoggingOptions(),
successOptions: (text) => ({
totalResults: 1,
resultsShared: 1,
responseCharCount: text.length,
}),
}, async () => {
const userSummary = new UserSummaryPrompt(hfToken);
return userSummary.generateSummary(params);
});
return {
description: `User summary for ${params.user_id}`,
messages: [
{
role: 'user',
content: {
type: 'text',
text: summaryText,
},
},
],
};
});
server.prompt(PAPER_SUMMARY_PROMPT_CONFIG.name, PAPER_SUMMARY_PROMPT_CONFIG.description, PAPER_SUMMARY_PROMPT_CONFIG.schema.shape, async (params) => {
const summaryText = await runWithQueryLogging(logPromptQuery, {
methodName: PAPER_SUMMARY_PROMPT_CONFIG.name,
query: params.paper_id,
parameters: { paper_id: params.paper_id },
baseOptions: getLoggingOptions(),
successOptions: (text) => ({
totalResults: 1,
resultsShared: 1,
responseCharCount: text.length,
}),
}, async () => {
const paperSummary = new PaperSummaryPrompt(hfToken);
return paperSummary.generateSummary(params);
});
return {
description: `Paper summary for ${params.paper_id}`,
messages: [
{
role: 'user',
content: {
type: 'text',
text: summaryText,
},
},
],
};
});
server.prompt(MODEL_DETAIL_PROMPT_CONFIG.name, MODEL_DETAIL_PROMPT_CONFIG.description, MODEL_DETAIL_PROMPT_CONFIG.schema.shape, async (params) => {
const result = await runWithQueryLogging(logPromptQuery, {
methodName: MODEL_DETAIL_PROMPT_CONFIG.name,
query: params.model_id,
parameters: { model_id: params.model_id },
baseOptions: getLoggingOptions(),
successOptions: (details) => ({
totalResults: details.totalResults,
resultsShared: details.resultsShared,
responseCharCount: details.formatted.length,
}),
}, async () => {
const modelDetail = new ModelDetailTool(hfToken, undefined);
return modelDetail.getDetails(params.model_id, true);
});
return {
description: `Model details for ${params.model_id}`,
messages: [
{
role: 'user',
content: {
type: 'text',
text: result.formatted,
},
},
],
};
});
server.prompt(DATASET_DETAIL_PROMPT_CONFIG.name, DATASET_DETAIL_PROMPT_CONFIG.description, DATASET_DETAIL_PROMPT_CONFIG.schema.shape, async (params) => {
const result = await runWithQueryLogging(logPromptQuery, {
methodName: DATASET_DETAIL_PROMPT_CONFIG.name,
query: params.dataset_id,
parameters: { dataset_id: params.dataset_id },
baseOptions: getLoggingOptions(),
successOptions: (details) => ({
totalResults: details.totalResults,
resultsShared: details.resultsShared,
responseCharCount: details.formatted.length,
}),
}, async () => {
const datasetDetail = new DatasetDetailTool(hfToken, undefined);
return datasetDetail.getDetails(params.dataset_id, true);
});
return {
description: `Dataset details for ${params.dataset_id}`,
messages: [
{
role: 'user',
content: {
type: 'text',
text: result.formatted,
},
},
],
};
});
toolInstances[SEMANTIC_SEARCH_TOOL_CONFIG.name] = server.tool(SEMANTIC_SEARCH_TOOL_CONFIG.name, SEMANTIC_SEARCH_TOOL_CONFIG.description, SEMANTIC_SEARCH_TOOL_CONFIG.schema.shape, SEMANTIC_SEARCH_TOOL_CONFIG.annotations, async (params) => {
const result = await runWithQueryLogging(logSearchQuery, {
methodName: SEMANTIC_SEARCH_TOOL_CONFIG.name,
query: params.query,
parameters: { limit: params.limit, mcp: params.mcp },
baseOptions: getLoggingOptions(),
successOptions: (formatted) => ({
totalResults: formatted.totalResults,
resultsShared: formatted.resultsShared,
responseCharCount: formatted.formatted.length,
}),
}, async () => {
const semanticSearch = new SpaceSearchTool(hfToken);
const searchResult = await semanticSearch.search(params.query, params.limit, params.mcp);
return formatSearchResults(params.query, searchResult.results, searchResult.totalCount);
});
return {
content: [{ type: 'text', text: result.formatted }],
};
});
toolInstances[MODEL_SEARCH_TOOL_CONFIG.name] = server.tool(MODEL_SEARCH_TOOL_CONFIG.name, MODEL_SEARCH_TOOL_CONFIG.description, MODEL_SEARCH_TOOL_CONFIG.schema.shape, MODEL_SEARCH_TOOL_CONFIG.annotations, async (params) => {
const filters = [];
if (params.task)
filters.push(params.task);
if (params.library)
filters.push(params.library);
const repoParams = {
query: params.query,
repo_types: ['model'],
author: params.author,
sort: params.sort,
limit: params.limit,
...(filters.length > 0 ? { filters } : {}),
};
const result = await runWithQueryLogging(logSearchQuery, {
methodName: MODEL_SEARCH_TOOL_CONFIG.name,
query: params.query || `sort:${params.sort || 'trendingScore'}`,
parameters: params,
baseOptions: getLoggingOptions(),
successOptions: (formatted) => ({
totalResults: formatted.totalResults,
resultsShared: formatted.resultsShared,
responseCharCount: formatted.formatted.length,
}),
}, async () => {
const repoSearch = new RepoSearchTool(hfToken);
return repoSearch.searchWithParams(repoParams);
});
return {
content: [{ type: 'text', text: result.formatted }],
};
});
toolInstances[REPO_SEARCH_TOOL_CONFIG.name] = server.tool(REPO_SEARCH_TOOL_CONFIG.name, REPO_SEARCH_TOOL_CONFIG.description, REPO_SEARCH_TOOL_CONFIG.schema.shape, REPO_SEARCH_TOOL_CONFIG.annotations, async (params) => {
const result = await runWithQueryLogging(logSearchQuery, {
methodName: REPO_SEARCH_TOOL_CONFIG.name,
query: params.query || `sort:${params.sort || 'trendingScore'}`,
parameters: params,
baseOptions: getLoggingOptions(),
successOptions: (formatted) => ({
totalResults: formatted.totalResults,
resultsShared: formatted.resultsShared,
responseCharCount: formatted.formatted.length,
}),
}, async () => {
const repoSearch = new RepoSearchTool(hfToken);
return repoSearch.searchWithParams(params);
});
return {
content: [{ type: 'text', text: result.formatted }],
};
});
const createRepoToolConfig = CreateRepoTool.createToolConfig();
toolInstances[createRepoToolConfig.name] = server.registerTool(createRepoToolConfig.name, {
title: createRepoToolConfig.annotations.title,
description: createRepoToolConfig.description,
inputSchema: createRepoToolConfig.schema.shape,
annotations: createRepoToolConfig.annotations,
}, async (params) => {
const result = await runWithQueryLogging(logPromptQuery, {
methodName: createRepoToolConfig.name,
query: `${params.repo_type ?? 'model'}:${params.name}`,
parameters: params,
baseOptions: getLoggingOptions(),
successOptions: (created) => ({
resultsShared: 1,
responseCharCount: formatCreateRepoResult(created).length,
}),
}, async () => {
const createRepoTool = new CreateRepoTool(hfToken);
return createRepoTool.create(params);
});
return {
content: [{ type: 'text', text: formatCreateRepoResult(result) }],
};
});
toolInstances[MODEL_DETAIL_TOOL_CONFIG.name] = server.tool(MODEL_DETAIL_TOOL_CONFIG.name, MODEL_DETAIL_TOOL_CONFIG.description, MODEL_DETAIL_TOOL_CONFIG.schema.shape, MODEL_DETAIL_TOOL_CONFIG.annotations, async (params) => {
const result = await runWithQueryLogging(logPromptQuery, {
methodName: MODEL_DETAIL_TOOL_CONFIG.name,
query: params.model_id,
parameters: { model_id: params.model_id },
baseOptions: getLoggingOptions(),
successOptions: (details) => ({
totalResults: details.totalResults,
resultsShared: details.resultsShared,
responseCharCount: details.formatted.length,
}),
}, async () => {
const modelDetail = new ModelDetailTool(hfToken, undefined);
return modelDetail.getDetails(params.model_id, false);
});
return {
content: [{ type: 'text', text: result.formatted }],
};
});
toolInstances[PAPER_SEARCH_TOOL_CONFIG.name] = server.tool(PAPER_SEARCH_TOOL_CONFIG.name, PAPER_SEARCH_TOOL_CONFIG.description, PAPER_SEARCH_TOOL_CONFIG.schema.shape, PAPER_SEARCH_TOOL_CONFIG.annotations, async (params) => {
const result = await runWithQueryLogging(logSearchQuery, {
methodName: PAPER_SEARCH_TOOL_CONFIG.name,
query: params.query,
parameters: { results_limit: params.results_limit, concise_only: params.concise_only },
baseOptions: getLoggingOptions(),
successOptions: (formatted) => ({
totalResults: formatted.totalResults,
resultsShared: formatted.resultsShared,
responseCharCount: formatted.formatted.length,
}),
}, async () => {
const paperSearchTool = new PaperSearchTool(hfToken);
return paperSearchTool.search(params.query, params.results_limit, params.concise_only);
});
return {
content: [{ type: 'text', text: result.formatted }],
};
});
toolInstances[DATASET_SEARCH_TOOL_CONFIG.name] = server.tool(DATASET_SEARCH_TOOL_CONFIG.name, DATASET_SEARCH_TOOL_CONFIG.description, DATASET_SEARCH_TOOL_CONFIG.schema.shape, DATASET_SEARCH_TOOL_CONFIG.annotations, async (params) => {
const repoParams = {
query: params.query,
repo_types: ['dataset'],
author: params.author,
sort: params.sort,
limit: params.limit,
...(params.tags && params.tags.length > 0 ? { filters: params.tags } : {}),
};
const result = await runWithQueryLogging(logSearchQuery, {
methodName: DATASET_SEARCH_TOOL_CONFIG.name,
query: params.query || `sort:${params.sort || 'trendingScore'}`,
parameters: params,
baseOptions: getLoggingOptions(),
successOptions: (formatted) => ({
totalResults: formatted.totalResults,
resultsShared: formatted.resultsShared,
responseCharCount: formatted.formatted.length,
}),
}, async () => {
const repoSearch = new RepoSearchTool(hfToken);
return repoSearch.searchWithParams(repoParams);
});
return {
content: [{ type: 'text', text: result.formatted }],
};
});
toolInstances[DATASET_DETAIL_TOOL_CONFIG.name] = server.tool(DATASET_DETAIL_TOOL_CONFIG.name, DATASET_DETAIL_TOOL_CONFIG.description, DATASET_DETAIL_TOOL_CONFIG.schema.shape, DATASET_DETAIL_TOOL_CONFIG.annotations, async (params) => {
const result = await runWithQueryLogging(logPromptQuery, {
methodName: DATASET_DETAIL_TOOL_CONFIG.name,
query: params.dataset_id,
parameters: { dataset_id: params.dataset_id },
baseOptions: getLoggingOptions(),
successOptions: (details) => ({
totalResults: details.totalResults,
resultsShared: details.resultsShared,
responseCharCount: details.formatted.length,
}),
}, async () => {
const datasetDetail = new DatasetDetailTool(hfToken, undefined);
return datasetDetail.getDetails(params.dataset_id, false);
});
return {
content: [{ type: 'text', text: result.formatted }],
};
});
const hubInspectReadmeAllowed = hasReadmeFlag(toolSelection.enabledToolIds);
const hubInspectDescription = hubInspectReadmeAllowed
? `${HUB_REPO_DETAILS_TOOL_CONFIG.description} README file may be requested from the external repository.`
: HUB_REPO_DETAILS_TOOL_CONFIG.description;
const hubInspectBaseShape = HUB_REPO_DETAILS_TOOL_CONFIG.schema.shape;
const hubInspectSchemaShape = hubInspectReadmeAllowed
? hubInspectBaseShape
: (() => {
const { include_readme: _omit, ...rest } = hubInspectBaseShape;
return rest;
})();
toolInstances[HUB_REPO_DETAILS_TOOL_CONFIG.name] = server.tool(HUB_REPO_DETAILS_TOOL_CONFIG.name, hubInspectDescription, hubInspectSchemaShape, HUB_REPO_DETAILS_TOOL_CONFIG.annotations, async (params) => {
const currentSelection = await toolSelectionStrategy.selectTools(toolSelectionContext);
const allowReadme = hasReadmeFlag(currentSelection.enabledToolIds);
const wantReadme = params.include_readme === true;
const includeReadme = allowReadme && wantReadme;
const repoIdsParam = params.repo_ids;
const repoIds = Array.isArray(repoIdsParam) ? repoIdsParam : [];
const firstRepoId = typeof repoIds[0] === 'string' ? repoIds[0] : '';
const repoType = params.repo_type;
const repoTypeSafe = repoType === 'model' || repoType === 'dataset' || repoType === 'space' ? repoType : undefined;
const operationsParam = params.operations;
const operations = Array.isArray(operationsParam)
? operationsParam.filter((operation) => typeof operation === 'string')
: undefined;
const config = params.config;
const split = params.split;
const offset = params.offset;
const limit = params.limit;
const result = await runWithQueryLogging(logPromptQuery, {
methodName: HUB_REPO_DETAILS_TOOL_CONFIG.name,
query: firstRepoId,
parameters: {
count: repoIds.length,
repo_type: repoTypeSafe,
include_readme: includeReadme,
operations,
config: typeof config === 'string' ? config : undefined,
split: typeof split === 'string' ? split : undefined,
offset: typeof offset === 'number' ? offset : undefined,
limit: typeof limit === 'number' ? limit : undefined,
},
baseOptions: getLoggingOptions(),
successOptions: (details) => ({
totalResults: details.totalResults,
resultsShared: details.resultsShared,
responseCharCount: details.formatted.length,
}),
}, async () => {
const tool = new HubInspectTool(hfToken, undefined);
return tool.inspect(params, includeReadme);
});
return {
content: [{ type: 'text', text: result.formatted }],
};
});
toolInstances[DOCS_SEMANTIC_SEARCH_CONFIG.name] = server.tool(DOCS_SEMANTIC_SEARCH_CONFIG.name, DOCS_SEMANTIC_SEARCH_CONFIG.description, DOCS_SEMANTIC_SEARCH_CONFIG.schema.shape, DOCS_SEMANTIC_SEARCH_CONFIG.annotations, async (params) => {
const result = await runWithQueryLogging(logSearchQuery, {
methodName: DOCS_SEMANTIC_SEARCH_CONFIG.name,
query: params.query,
parameters: { product: params.product },
baseOptions: getLoggingOptions(),
successOptions: (formatted) => ({
totalResults: formatted.totalResults,
resultsShared: formatted.resultsShared,
responseCharCount: formatted.formatted.length,
}),
}, async () => {
const docSearch = new DocSearchTool(hfToken);
return docSearch.search(params);
});
return {
content: [{ type: 'text', text: result.formatted }],
};
});
toolInstances[DOC_FETCH_CONFIG.name] = server.tool(DOC_FETCH_CONFIG.name, DOC_FETCH_CONFIG.description, DOC_FETCH_CONFIG.schema.shape, DOC_FETCH_CONFIG.annotations, async (params) => {
const results = await runWithQueryLogging(logSearchQuery, {
methodName: DOC_FETCH_CONFIG.name,
query: params.doc_url,
parameters: { offset: params.offset },
baseOptions: getLoggingOptions(),
successOptions: (content) => ({
totalResults: 1,
resultsShared: 1,
responseCharCount: content.length,
}),
}, async () => {
const docFetch = new DocFetchTool();
return docFetch.fetch(params);
});
return {
content: [{ type: 'text', text: results }],
};
});
const duplicateToolConfig = DuplicateSpaceTool.createToolConfig(username);
toolInstances[duplicateToolConfig.name] = server.tool(duplicateToolConfig.name, duplicateToolConfig.description, duplicateToolConfig.schema.shape, duplicateToolConfig.annotations, async (params) => {
const duplicateSpace = new DuplicateSpaceTool(hfToken, username);
const result = await duplicateSpace.duplicate(params);
return {
content: [{ type: 'text', text: formatDuplicateResult(result) }],
};
});
const spaceInfoToolConfig = SpaceInfoTool.createToolConfig(username);
toolInstances[spaceInfoToolConfig.name] = server.tool(spaceInfoToolConfig.name, spaceInfoToolConfig.description, spaceInfoToolConfig.schema.shape, spaceInfoToolConfig.annotations, async (params) => {
const spaceInfoTool = new SpaceInfoTool(hfToken, username);
const result = await formatSpaceInfoResult(spaceInfoTool, params);
return {
content: [{ type: 'text', text: result }],
};
});
const spaceFilesToolConfig = SpaceFilesTool.createToolConfig(username);
toolInstances[spaceFilesToolConfig.name] = server.tool(spaceFilesToolConfig.name, spaceFilesToolConfig.description, spaceFilesToolConfig.schema.shape, spaceFilesToolConfig.annotations, async (params) => {
const spaceFilesTool = new SpaceFilesTool(hfToken, username);
const result = await spaceFilesTool.listFiles(params);
return {
content: [{ type: 'text', text: result }],
};
});
toolInstances[USE_SPACE_TOOL_CONFIG.name] = server.tool(USE_SPACE_TOOL_CONFIG.name, USE_SPACE_TOOL_CONFIG.description, USE_SPACE_TOOL_CONFIG.schema.shape, USE_SPACE_TOOL_CONFIG.annotations, async (params) => {
const result = await runWithQueryLogging(logPromptQuery, {
methodName: USE_SPACE_TOOL_CONFIG.name,
query: params.space_id,
parameters: { space_id: params.space_id },
baseOptions: getLoggingOptions(),
successOptions: (useSpaceResult) => ({
totalResults: useSpaceResult.metadata.totalResults,
resultsShared: useSpaceResult.metadata.resultsShared,
responseCharCount: useSpaceResult.metadata.formatted.length,
}),
}, async () => {
const useSpaceTool = new UseSpaceTool(hfToken, undefined);
return formatUseSpaceResult(useSpaceTool, params);
});
return {
content: result.content,
};
});
toolInstances[HF_JOBS_TOOL_CONFIG.name] = server.tool(HF_JOBS_TOOL_CONFIG.name, HF_JOBS_TOOL_CONFIG.description, HF_JOBS_TOOL_CONFIG.schema.shape, HF_JOBS_TOOL_CONFIG.annotations, async (params) => {
const isAuthenticated = !!hfToken;
const loggedOperation = params.operation ?? 'no-operation';
const result = await runWithQueryLogging(logSearchQuery, {
methodName: HF_JOBS_TOOL_CONFIG.name,
query: loggedOperation,
parameters: params.args || {},
baseOptions: getLoggingOptions(),
successOptions: (jobResult) => ({
totalResults: jobResult.totalResults,
resultsShared: jobResult.resultsShared,
responseCharCount: jobResult.formatted.length,
}),
}, async () => {
const jobsTool = new HfJobsTool(hfToken, isAuthenticated, username);
return jobsTool.execute(params);
});
return {
content: [{ type: 'text', text: result.formatted }],
...(result.isError && { isError: true }),
};
});
const dynamicSpaceToolConfig = getDynamicSpaceToolConfig();
toolInstances[dynamicSpaceToolConfig.name] = server.tool(dynamicSpaceToolConfig.name, dynamicSpaceToolConfig.description, dynamicSpaceToolConfig.schema.shape, dynamicSpaceToolConfig.annotations, async (params, extra) => {
const { gradio } = extractAuthBouquetAndMix(headers);
if (params.operation === 'invoke' && gradio === 'none') {
const errorMessage = 'The invoke operation is disabled because gradio=none is set. ' +
'To use invoke, remove gradio=none from your headers or set gradio to a space ID. ' +
`You can still use operation=${VIEW_PARAMETERS} to inspect the tool schema.`;
return {
content: [{ type: 'text', text: errorMessage }],
isError: true,
};
}
const loggedOperation = params.operation ?? 'no-operation';
if (params.operation === 'invoke') {
const startTime = Date.now();
let success = false;
try {
const spaceTool = new SpaceTool(hfToken);
const result = await spaceTool.execute(params, extra);
if ('result' in result && result.result) {
const invokeResult = result;
success = !invokeResult.isError;
const stripImageContent = noImageContentHeaderEnabled || toolSelection.enabledToolIds.includes('NO_GRADIO_IMAGE_CONTENT');
const postProcessOptions = {
stripImageContent,
toolName: dynamicSpaceToolConfig.name,
outwardFacingName: dynamicSpaceToolConfig.name,
sessionInfo,
spaceName: params.space_name,
};
const processedResult = applyResultPostProcessing(invokeResult.result, postProcessOptions);
const warningsContent = invokeResult.warnings.length > 0
? [
{
type: 'text',
text: (invokeResult.warnings.length === 1 ? 'Warning:\n' : 'Warnings:\n') +
invokeResult.warnings.map((w) => `- ${w}`).join('\n') +
'\n',
},
]
: [];
const durationMs = Date.now() - startTime;
const responseContent = [...warningsContent, ...processedResult.content];
logGradioEvent(params.space_name || 'unknown-space', sessionInfo?.clientSessionId || 'unknown', {
durationMs,
isAuthenticated: !!hfToken,
clientName: sessionInfo?.clientInfo?.name,
clientVersion: sessionInfo?.clientInfo?.version,
success,
error: invokeResult.isError ? JSON.stringify(responseContent) : undefined,
responseSizeBytes: JSON.stringify(responseContent).length,
isDynamic: true,
});
return {
content: responseContent,
...(invokeResult.isError && { isError: true }),
};
}
const toolResult = result;
success = !toolResult.isError;
const durationMs = Date.now() - startTime;
logSearchQuery(dynamicSpaceToolConfig.name, loggedOperation, params, {
...getLoggingOptions(),
totalResults: toolResult.totalResults,
resultsShared: toolResult.resultsShared,
responseCharCount: toolResult.formatted.length,
durationMs,
success,
});
return {
content: [{ type: 'text', text: toolResult.formatted }],
...(toolResult.isError && { isError: true }),
};
}
catch (err) {
const durationMs = Date.now() - startTime;
logGradioEvent(params.space_name || 'unknown-space', sessionInfo?.clientSessionId || 'unknown', {
durationMs,
isAuthenticated: !!hfToken,
clientName: sessionInfo?.clientInfo?.name,
clientVersion: sessionInfo?.clientInfo?.version,
success: false,
error: err,
isDynamic: true,
});
throw err;
}
}
const toolResult = await runWithQueryLogging(logSearchQuery, {
methodName: dynamicSpaceToolConfig.name,
query: loggedOperation,
parameters: params,
baseOptions: getLoggingOptions(),
successOptions: (result) => ({
totalResults: result.totalResults,
resultsShared: result.resultsShared,
responseCharCount: result.formatted.length,
}),
}, async () => {
const spaceTool = new SpaceTool(hfToken);
const result = await spaceTool.execute(params, extra);
return result;
});
return {
content: [{ type: 'text', text: toolResult.formatted }],
...(toolResult.isError && { isError: true }),
};
});
if (sessionInfo?.clientInfo?.name === 'openai-mcp') {
logger.debug('Registering Gradio widget resource for skybridge client');
const widgetConfig = createGradioWidgetResourceConfig(version);
server.registerResource(widgetConfig.name, widgetConfig.uri, {}, async () => ({
contents: [
{
uri: widgetConfig.uri,
mimeType: widgetConfig.mimeType,
text: widgetConfig.htmlContent,
_meta: widgetConfig.metadata,
},
],
}));
}
if (skillCatalog && hasSkills) {
registerSkillResources(server, skillCatalog);
}
const applyToolStates = async () => {
logger.info({
mode: toolSelection.mode,
reason: toolSelection.reason,
enabledCount: toolSelection.enabledToolIds.length,
totalTools: Object.keys(toolInstances).length,
mixedBouquet: toolSelection.mixedBouquet?.join(','),
}, 'Tool selection strategy applied');
for (const [toolName, toolInstance] of Object.entries(toolInstances)) {
if (toolSelection.enabledToolIds.includes(toolName)) {
toolInstance.enable();
}
else {
toolInstance.disable();
}
}
};
const transportInfo = sharedApiClient.getTransportInfo();
registerCapabilities(server, sharedApiClient, {
hasResources: !clientDenied && sessionInfo?.clientInfo?.name === 'openai-mcp',
hasSkills,
});
if (!skipGradio) {
void applyToolStates();
if (!transportInfo?.jsonResponseEnabled && !transportInfo?.externalApiMode) {
const toolStateChangeHandler = (toolId, enabled) => {
const toolInstance = toolInstances[toolId];
if (toolInstance) {
if (enabled && (!AUTHENTICATED_BUILTIN_TOOL_IDS.includes(toolId) || hfToken)) {
toolInstance.enable();
}
else {
toolInstance.disable();
}
logger.debug({ toolId, enabled }, 'Applied single tool state change');
}
};
sharedApiClient.on('toolStateChange', toolStateChangeHandler);
server.server.onclose = () => {
sharedApiClient.removeListener('toolStateChange', toolStateChangeHandler);
logger.debug('Removed toolStateChange listener for closed server');
};
}
}
return { server, userDetails, enabledToolIds: toolSelection.enabledToolIds };
};
};
//# sourceMappingURL=mcp-server.js.map

Xet Storage Details

Size:
40.4 kB
·
Xet hash:
c3e4aca74b7bad59772e66179846b04dd4ddfaca05db8cebff1b78b32047e385

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.