MCPcopy Index your code
hub / github.com/simstudioai/sim / executeTool

Function executeTool

apps/sim/tools/index.ts:905–1360  ·  view source on GitHub ↗
(
  toolId: string,
  params: Record<string, any>,
  options: ExecuteToolOptions = {}
)

Source from the content-addressed store, hash-verified

903 * All requests go directly - internal routes use regular fetch, external use SSRF-protected fetch
904 */
905export async function executeTool(
906 toolId: string,
907 params: Record<string, any>,
908 options: ExecuteToolOptions = {}
909): Promise<ToolResponse> {
910 const { skipPostProcess = false, executionContext, signal } = options
911 // Fall back to the workflow execution's abort signal so plan-based execution timeouts
912 // and cancellation propagate to tool fetches when the caller passes no explicit signal.
913 const effectiveSignal = signal ?? executionContext?.abortSignal
914 // Capture start time for precise timing
915 const startTime = new Date()
916 const startTimeISO = startTime.toISOString()
917 const requestId = generateRequestId()
918
919 // Hoisted so the outer catch can attribute a thrown failure to the chosen key.
920 let hostedKeyForMetrics: { provider: string; tool: string; key: string } | undefined
921
922 try {
923 let tool: ToolConfig | undefined
924
925 // Normalize tool ID to strip resource suffixes (e.g., workflow_executor_<uuid> -> workflow_executor)
926 const normalizedToolId = normalizeToolId(toolId)
927
928 const scope = resolveToolScope(params, executionContext)
929
930 const toolKind: 'skill' | 'custom' | 'mcp' | undefined =
931 normalizedToolId === 'load_skill' || normalizedToolId === 'load_user_skill'
932 ? 'skill'
933 : isCustomTool(normalizedToolId)
934 ? 'custom'
935 : isMcpTool(normalizedToolId)
936 ? 'mcp'
937 : undefined
938
939 // Runs for ALL tools (not just kinded ones) so the per-tool `deniedTools`
940 // denylist is enforced alongside the existing mcp/custom/skill gates.
941 if (scope.userId && scope.workspaceId) {
942 await assertPermissionsAllowed({
943 userId: scope.userId,
944 workspaceId: scope.workspaceId,
945 toolId: normalizedToolId,
946 toolKind,
947 ctx: executionContext,
948 })
949 }
950
951 if (normalizedToolId === 'load_skill' || normalizedToolId === 'load_user_skill') {
952 const skillName = params.skill_name
953 if (!skillName || !scope.workspaceId) {
954 return {
955 success: false,
956 output: { error: 'Missing skill_name or workspace context' },
957 error: 'Missing skill_name or workspace context',
958 }
959 }
960 const content = await resolveSkillContent(skillName, scope.workspaceId)
961 if (!content) {
962 return {

Callers 15

index.test.tsFile · 0.90
testErrorFormatFunction · 0.90
executeToolCallsBatchFunction · 0.90
index.tsFile · 0.90
index.tsFile · 0.90
index.tsFile · 0.90
index.tsFile · 0.90
index.tsFile · 0.90
index.tsFile · 0.90
index.tsFile · 0.90

Calls 15

generateRequestIdFunction · 0.90
normalizeToolIdFunction · 0.90
isCustomToolFunction · 0.90
isMcpToolFunction · 0.90
assertPermissionsAllowedFunction · 0.90
resolveSkillContentFunction · 0.90
getToolFunction · 0.90
getInternalApiBaseUrlFunction · 0.90
generateInternalTokenFunction · 0.90
toErrorFunction · 0.90
resolveToolScopeFunction · 0.85

Tested by 1

testErrorFormatFunction · 0.72