Skip to content
Talk to an Engineer Dashboard

Invoke tools for your AI agent

Execute tools directly, customize their behavior with modifiers, and build agentic workflows where LLMs drive tool selection.

Agent Auth supports three approaches to tool calling: execute tools directly with explicit parameters, customize tool behavior with pre- and post-modifiers, or let an LLM select and invoke tools automatically based on user input.

Using Scalekit SDK, you can execute any action on behalf of a user using the following parameters:

  • user context
  • tool_name
  • tool_input_parameters
# Fetch recent emails
tool_response = actions.execute_tool(
# tool input parameters
tool_input={
'query': 'is:unread',
'max_results': 5
},
# tool name to execute
tool_name='gmail_fetch_mails',
# connected_account gives the user context
connected_account_id=connected_account.id,
)
print(f'Recent emails: {tool_response.result}')

Tool modifiers intercept and modify tool inputs and outputs using decorators.

  • Pre-modifiers: Modify tool inputs before execution
  • Post-modifiers: Modify tool outputs after execution

Pre-modifiers modify tool inputs before execution to enforce consistent filters, add security constraints, override LLM decisions with required behavior, or set default configurations.

Example: Gmail unread filter
from scalekit.actions.models.tool_input_output import ToolInput
# For example, we can modify the query to only fetch unread emails
# regardless of what the user asks for or what the LLM determines.
@actions.pre_modifier(tool_names=["gmail_fetch_mails"])
def gmail_pre_modifier(tool_input: ToolInput):
tool_input['query'] = 'is:unread'
return tool_input

This modifier:

  • Intercepts all calls to gmail_fetch_mails
  • Forces the query to always search for unread emails only
  • Ensures consistent behavior regardless of user input or LLM interpretation

Multiple tools example

@actions.pre_modifier(tool_names=["gmail_fetch_mails", "gmail_search_emails"])
def email_security_modifier(tool_input: ToolInput):
# Add security constraints to all email operations
tool_input['include_spam'] = False
tool_input['max_results'] = min(tool_input.get('max_results', 10), 50)
return tool_input

Post-modifiers modify tool outputs after execution to reduce token usage, transform formats for LLM consumption, extract specific data, or standardize output structure.

Example: Gmail response filtering
from scalekit.actions.models.tool_input_output import ToolOutput
# Sometimes, the tool output needs to be modified in a deterministic way after the tool is executed.
# For example, we can modify the output to only return the first email snippet regardless of what the tool returns.
# This is an effective way to reduce the amount of data that is returned to the LLM to save on tokens.
@actions.post_modifier(tool_names=["gmail_fetch_mails"])
def gmail_post_modifier(output: ToolOutput):
# Only return the first email snippet
# Should return a dict
# Response should be a dict with a key 'response'
for snippet in output['messages']:
print(f"Email snippet: {snippet['snippet']}")
return {"response": output['messages'][0]['snippet']}

This modifier:

  • Processes the response from gmail_fetch_mails
  • Extracts only the first email snippet instead of returning all emails
  • Reduces token usage by sending minimal data to the LLM

Let an LLM determine which tool to call and with what parameters based on user input. This quickstart uses LangChain to build an agent that authenticates a user with Gmail and fetches their last 5 unread emails.

Prerequisites: Scalekit API credentials (Client ID and Client Secret) and a Python development environment.

  1. Install the Scalekit Python SDK and initialize the client with your API credentials:

    pip install scalekit-sdk-python langchain

    import scalekit.client
    import os
    scalekit_client = scalekit.client.ScalekitClient(
    client_id=os.getenv("SCALEKIT_CLIENT_ID"),
    client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
    env_url=os.getenv("SCALEKIT_ENV_URL"),
    )
    actions = scalekit_client.actions

  2. Authorize a user to access their Gmail account by creating a connected account. This represents the user’s connection to their Gmail account:

    # Create a connected account for user if it doesn't exist already
    response = actions.get_or_create_connected_account(
    connection_name="gmail",
    identifier="user_123"
    )
    connected_account = response.connected_account
    print(f'Connected account created: {connected_account.id}')
  3. For Scalekit to execute tools on behalf of the user, the user must grant authorization to access their Gmail account. Scalekit automatically handles the entire OAuth workflow, including token refresh.

    # If the user hasn't yet authorized the gmail connection or if the user's access token is expired,
    # generate a magic link and redirect the user to this link so that the user can complete authorization
    if(connected_account.status != "ACTIVE"):
    link_response = actions.get_authorization_link(
    connection_name="gmail",
    identifier="user_123"
    )
    print(f"🔗click on the link to authorize gmail", link_response.link)
    input(f"⎆ Press Enter after authorizing gmail...")
    # In a real app, redirect the user to this URL so that the user can complete the authentication process for their gmail account
  4. Build a simple agent that fetches the last 5 unread emails from the user’s inbox and generates a summary.

    from langchain_core.prompts import SystemMessagePromptTemplate, MessagesPlaceholder, HumanMessagePromptTemplate,PromptTemplate, ChatPromptTemplate
    # use scalekit SDK to fetch all GMAIL tools in langchain format
    tools = actions.langchain.get_tools(
    identifier=identifier,
    providers = ["GMAIL"], # all tools for provider used by default
    page_size=100
    )
    prompt = ChatPromptTemplate.from_messages([
    SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template="You are a helpful assistant. Use tools if needed")),
    MessagesPlaceholder(variable_name="chat_history", optional=True),
    HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=["input"], template="{input}")),
    MessagesPlaceholder(variable_name="agent_scratchpad")
    ])
    llm = ChatOpenAI(model="gpt-4o")
    agent = create_openai_tools_agent(llm, tools, prompt)
    agent_executor = AgentExecutor(agent=agent, tools=tools,verbose=True)
    result = agent_executor.invoke({"input":"fetch my last 5 unread emails and summarize it"}
    )

For more detailed framework-specific implementations, explore the AI framework guides: