Skip to main content
Version: Latest (4.11.0)

Building AI Agents — Tools Guide

Configure and select tools for ServiceNow AI Agents and AI Agentic Workflows using the Fluent SDK. Covers tool types (CRUD, script, OOB, reference-based, RAG), tool discovery, execution mode, output transformation, and multi-tool composition patterns.


Tool Selection Guide

Selection Priority

  1. OOB tools when available (e.g., Web Search, RAG, Knowledge Graph)
  2. Reference-based tools (action, subflow, capability, catalog, topic)
  3. CRUD tools for database operations
  4. Script tools only when no other tool type fits

Never use CRUD tools for journal fields (work_notes, comments). Always use Script tools with GlideRecordSecure.

Tool Selection Table

NeedTool TypeWhy
Read/search recordsCRUD (lookup)Direct table query
Create new recordsCRUD (create)Maps inputs to columns
Modify recordsCRUD (update)Query + field update
Remove recordsCRUD (delete)Query-based deletion
Custom logicScriptFull JavaScript control
Web informationOOB (web_automation)Auto-linked OOB tool
Semantic/keyword searchRAG (rag)Structured search with ValueLabelType inputs
Flow Designer actionAction (action)Triggers existing flows
Flow Designer subflowSubFlow (subflow)Triggers existing multi-step flows
AI skillCapability (capability)Links to GenAI skills
Service Catalog requestCatalog (catalog)Links to catalog items
Virtual Agent conversationTopic (topic / topic_block)Links to VA topics

CRUD Operation Selection by User Intent

When the user needs database operations, choose the right CRUD operations:

User IntentOperations to CreateExample
"Look up / search / find / get"lookup only"Find incidents by priority"
"Create / add / insert / submit"create + lookup (to verify)"Create a new incident"
"Update / modify / change / assign"lookup + update"Update incident status"
"Delete / remove"lookup + delete"Delete a record by ID"
"Full CRUD management"lookup + create + update"Manage incident records"

Tip: Most agents need a lookup tool even when the primary action is create/update/delete — the agent needs to find records before acting on them.

inputs Format by Tool Type

Tool typeinputs formatHas script field?
crudObject (ToolInputType) with operationName, table, inputFields, etc.No (auto-generated)
ragObject (RagInputType) with searchType, searchProfile, sources, etc. (all using ValueLabelType)No (auto-generated)
scriptArray of [{ name, description, mandatory, value? }]Yes
web_automationOmit (plugin provides defaults)No
Reference typesOmit (platform resolves at runtime)No
Other OOB typesOmit (plugin provides defaults)No

Mixing these up is a common error. If type is "crud", inputs MUST be an object with operationName. If type is "script", inputs MUST be an array.

Required Tool Properties

Every tool must have name and type. preMessage and postMessage are strongly recommended on every tool. Every agent must have processingMessage and postProcessingMessage (not available on workflows).

Valid tool.type Values

"script", "crud", "capability", "subflow", "action", "catalog", "topic", "topic_block", "web_automation", "rag"


Tool Discovery

Before creating any tool, check existing resources in the current app scope. Run all six checks in order — do not skip any. Only assign crud or a new script tool if all six checks return no usable match.

Resolve the scope sys_id first:

now-sdk query sys_scope -q 'scope=<scope_name>' -f 'sys_id,scope' -o json

Then run each check using the scope sys_id:

PriorityResource TypeTable to QueryencodedQueryIf match found, use tool type
1GenAI Skillsn_nowassist_skill_configsys_scope=<scope_sys_id>^active=truecapability + capabilityId
2SubFlowsys_hub_flowtype=subflow^sys_scope=<scope_sys_id>subflow + subflowId
3Flow Actionsys_hub_action_type_definitionsys_scope=<scope_sys_id>action + flowActionId
4Catalog Itemsc_cat_itemsys_scope=<scope_sys_id>^active=truecatalog + catalogItemId
5Conversational Topicsys_cs_topicsys_scope=<scope_sys_id>^active=truetopic + virtualAgentId
6Script Include methodsys_script_includesys_scope=<scope_sys_id>^active=truescript calling existing method

Rule: Only assign crud or a new script tool if all six checks return no usable match. Always inform the user which existing resource was reused.

Example discovery query:

now-sdk query sn_nowassist_skill_config -q 'sys_scope=<scope_sys_id>^active=true' -f 'sys_id,name' -o json

CRUD Tools

For database operations (create, lookup, update, delete). All CRUD tools require recordType: "custom" and type: "crud".

Operations

OperationRequired Fields
createtable, inputFields with mappedToColumn
lookuptable, queryCondition, returnFields (mandatory)
updatetable, queryCondition, inputFields with mappedToColumn
deletetable, queryCondition

queryCondition Syntax

Format: "column_name=={{input_field_name}}". Always verify column names by querying sys_dictionary before writing tools.

now-sdk query sys_dictionary -q 'name=<target_table>^internal_type!=collection' -f 'element,column_label' -o json
OperatorSyntaxExample
Equalsfield=valuestate=1
Not equalsfield!=valuestate!=7
Less/greaterfield<=valuepriority<=2
ContainsfieldLIKEvalueshort_descriptionLIKEnetwork
Starts withfieldSTARTSWITHvaluenumberSTARTSWITHINC
Is emptyfieldISEMPTYassigned_toISEMPTY
Is not emptyfieldISNOTEMPTYresolved_atISNOTEMPTY
OR^ORpriority=1^ORpriority=2

Dot-walking references in query conditions: Use dot notation to traverse reference fields: assigned_to.department=<value>. The left side of the operator must always be a valid column path on the target table.

Common Column Name Mistakes

Before writing any queryCondition or returnFields, query sys_dictionary to get actual column names. Do NOT guess or assume column names.

Common MistakeCorrect ColumnTable
incident_numbernumberincident
descshort_descriptionincident
description (for title)short_descriptionincident
Column from a different tableVerify table ownership

Always extract the element field from sys_dictionary results — these are the valid column names.

Lookup Best Practices

  • Always include { name: 'sys_id' } in returnFields — without it, the agent cannot chain operations (e.g., pass the record's sys_id to another tool)
  • Use LIKE operator for text-based searches (substring match instead of exact match)
  • Use multiple keyword inputs with OR for broader matching on natural language
  • Add keyword extraction guidance in agent instructions: "Extract 1-2 specific keywords from the user's request. Do NOT pass full sentences to the search tool."
  • Prefer number over sys_id as primary filter: number={{id}}^ORsys_id={{id}}
  • For reference fields in returnFields, include referenceConfig: { table: "sys_user", field: "name" }
  • Also include number (or the appropriate identifier) in returnFields so downstream tools can reference the record by its display value

Primary filter by table:

TablePrimary Filter FieldqueryCondition Pattern
incidentnumbernumber={{id}}^ORsys_id={{id}}
change_requestnumbernumber={{id}}^ORsys_id={{id}}
sc_requestnumbernumber={{id}}^ORsys_id={{id}}
sys_useruser_name or nameuser_name={{id}}^ORsys_id={{id}}
sys_user_groupnamename={{id}}^ORsys_id={{id}}
kb_knowledgenumbernumber={{id}}^ORsys_id={{id}}

When to use which pattern:

Search TypePatternExample
Known identifier (number, ID)Exact match with OR fallback: number={{id}}^ORsys_id={{id}}"Find INC0012345"
Known value (category, priority)Exact match: priority={{priority}}"Find P1 incidents"
Natural language / descriptionLIKE + multiple keywords with OR"email not syncing on Outlook"

Create — Mandatory Columns

For create operations, query sys_dictionary to discover mandatory columns:

now-sdk query sys_dictionary -q 'name=<table>^mandatory=true' -f 'column_label,element' -o json

Ensure ALL mandatory columns are captured in inputFields with mandatory: true. Update agent instructions to collect these fields from the user before creating.

mappedToColumn Self-Check

After writing each create or update tool, run this check before proceeding:

  1. Parse queryCondition and list every {{field_name}} variable — these are query-only fields
  2. For each entry in inputFields:
    • Is the field in the queryCondition variables? → It is a query field. Confirm it does NOT have mappedToColumn
    • Is the field NOT in queryCondition? → It is a write field. Confirm it HAS mappedToColumn set to a valid column name. If missing, add it now
  3. For create tools (no queryCondition): every inputField MUST have mappedToColumn — no exceptions
  4. Do NOT proceed to the next tool until this check passes

Without mappedToColumn, the plugin silently skips the field — the update finds the record but changes NOTHING, with no error.

// WRONG — missing mappedToColumn, update silently changes nothing
{ name: "new_status", mandatory: true }

// CORRECT — mappedToColumn maps input to table column
{ name: "new_status", mandatory: true, mappedToColumn: "state" }
inputFields: [
{ name: "record_id", mandatory: true }, // query input — in queryCondition (NO mappedToColumn)
{ name: "new_status", mandatory: true, mappedToColumn: "state" }, // write input
{ name: "priority", mandatory: true, mappedToColumn: "priority" } // write input
]

Delete Operation

For delete operations, configure queryCondition to identify the target record. No inputFields with mappedToColumn are needed — the tool only needs to find the record to delete.

{
name: 'Delete Record',
type: 'crud',
recordType: 'custom',
executionMode: 'copilot',
preMessage: 'Deleting the record...',
postMessage: 'Record deleted.',
inputs: {
operationName: 'delete',
table: 'incident',
queryCondition: 'number={{record_number}}',
inputFields: [
{ name: 'record_number', description: 'The incident number to delete', mandatory: true }
]
}
}

Script Tools

All script inputs are strings at runtime. Parse with parseInt(), JSON.parse(), etc. The inputs field for script tools is a simple array of input field definitions (unlike CRUD tools which use an object).

{
name: 'Calculate Priority',
type: 'script',
preMessage: 'Calculating results...',
postMessage: 'Calculation complete.',
inputs: [
{ name: 'impact', description: 'Impact level', mandatory: true },
{ name: 'urgency', description: 'Urgency level', mandatory: true }
],
script: `(function(inputs) {
var impact = parseInt(inputs.impact, 10);
var urgency = parseInt(inputs.urgency, 10);
var priority = Math.max(impact, urgency);
return { priority: priority, status: 'success' };
})(inputs);`
}

Key rules:

  • Always use GlideRecordSecure (not GlideRecord)
  • Do NOT add CDATA tags (plugin handles automatically)
  • inputSchema is auto-generated from inputs — do not specify it manually
  • Use module imports for server-side script files (or Now.include() for legacy scripts)

Calling Existing Script Includes

If a script include with a matching method exists, call it from within the Script tool instead of re-implementing logic:

{
name: 'Calculate Priority',
type: 'script',
preMessage: 'Calculating priority...',
postMessage: 'Priority calculated.',
inputs: [
{ name: 'impact', description: 'Impact level', mandatory: true },
{ name: 'urgency', description: 'Urgency level', mandatory: true }
],
script: `(function(inputs) {
var util = new MyAppUtils();
var result = util.calculatePriority(inputs.impact, inputs.urgency);
return { priority: result, status: "success" };
})(inputs);`
}

Journal Field Updates (work_notes, comments)

work_notes and comments are journal fields backed by sys_journal_field — they are not columns on the target table. CRUD update tools cannot write to them. Always use a Script tool:

{
name: 'Update Journal Field',
type: 'script',
preMessage: 'Updating journal field...',
postMessage: 'Journal field updated.',
inputs: [
{ name: 'table_name', description: 'Table name', mandatory: true },
{ name: 'record_sys_id', description: 'Record sys_id', mandatory: true },
{ name: 'field', description: 'Journal field (work_notes or comments)', mandatory: true },
{ name: 'note_text', description: 'Text to add', mandatory: true }
],
script: `(function(inputs) {
var gr = new GlideRecordSecure(inputs.table_name);
if (!gr.get(inputs.record_sys_id)) {
return { status: "error", message: "Record not found: " + inputs.record_sys_id };
}
if (inputs.field === "work_notes") {
gr.work_notes = inputs.note_text;
} else if (inputs.field === "comments") {
gr.comments = inputs.note_text;
} else {
return { status: "error", message: "Invalid journal field: " + inputs.field };
}
gr.update();
return { status: "success", message: "Journal field updated" };
})(inputs);`
}

GlideAggregate Pattern

Use GlideAggregate in script tools for counting or aggregating records:

{
name: 'Count Records',
type: 'script',
preMessage: 'Counting records...',
postMessage: 'Count complete.',
inputs: [
{ name: 'table', description: 'Table to count', mandatory: true },
{ name: 'filter', description: 'Encoded query filter', mandatory: true }
],
script: `(function(inputs) {
var ga = new GlideAggregate(inputs.table);
ga.addEncodedQuery(inputs.filter);
ga.addAggregate('COUNT');
ga.query();
var count = 0;
if (ga.next()) {
count = parseInt(ga.getAggregate('COUNT'), 10);
}
return { count: count, status: 'success' };
})(inputs);`
}

Reference-Based Tools

Each requires a type-specific reference field containing the target record's sys_id. Do NOT add inputs — the platform resolves inputs at runtime from the referenced record.

Tool TypeRequired FieldTarget TableUse For
actionflowActionIdsys_hub_action_type_definitionRunning a Flow Designer action
capabilitycapabilityIdsn_nowassist_skill_configUsing a GenAI skill (summarization, etc.)
subflowsubflowIdsys_hub_flowRunning a Flow Designer subflow
catalogcatalogItemIdsc_cat_itemSubmitting a Service Catalog request
topicvirtualAgentIdsys_cs_topicInvoking a Virtual Agent topic
topic_blockvirtualAgentIdsys_cs_topicInvoking a Virtual Agent topic block

OOB Tools

OOB tools only require type and name. The plugin auto-links to the existing OOB tool record.

{
type: 'web_automation',
name: 'AIA Web Search',
preMessage: 'Searching the web...',
postMessage: 'Web search results retrieved.'
}

Other supported OOB type: 'rag' — see the RAG (Search Retrieval) Tools section below.

Shared defaults across OOB tools:

PropertyDefault
activetrue
executionMode"autopilot"
displayOutputfalse
maxAutoExecutions10

Internal (Platform-Provided) Tools

These are platform-provided tools available to all agents. They do NOT need to be configured in the tools array — the platform provides them automatically. Reference them by name in agent instructions when the use case requires their behavior.

ToolCategoryPurposeUse When
organize_general_knowledgeInternalLeverages the agent's general knowledge to answer questionsAgent needs to reason or answer without querying a specific table or tool
mathInternalPerforms mathematical calculationsAgent needs arithmetic, aggregation, or formula evaluation
finishInternalSignals the agent has completed its taskAgent should explicitly terminate after delivering results
collect_input_from_userCommunicationPrompts the user for additional inputAgent needs clarification, confirmation, or missing data from the user
show_output_to_userCommunicationDisplays formatted output to the userAgent needs to present results, summaries, or status updates

Do NOT add these to the tools array — they are automatically available.

Usage in instructions example: "If the user's request is unclear, use collect_input_from_user to ask for clarification before proceeding."


RAG (Search Retrieval) Tools

RAG tools enable semantic search and document retrieval from ServiceNow AI Search indexes. The type for RAG tools in Fluent is 'rag' and requires structured inputs configuration with ValueLabelType objects.

Search Types

TypeDescriptionRequired Fields
'keyword'Simple text matchingNone
'semantic'Semantic search using embeddingssemanticIndexes (array of ValueLabelType)
'hybrid'Combines keyword and semanticsemanticIndexes (array of ValueLabelType)

Default to hybrid when a published profile with active indexes exists. If no active semantic indexes are linked to the picked sources, fall back to keyword.

Note: The query description is generated using the searchProfile.label. semanticIndexes and documentMatchThreshold are only included in the generated schema for semantic and hybrid search types. fields and searchResultsLimit apply to all search types.

Existing Tool Discovery

Before creating a new RAG tool, check whether an existing one already covers the need — duplicate RAG tools waste search profile setup and can confuse tool selection at runtime.

now-sdk query sn_aia_agent_tool_m2m -q 'tool.nameLIKEAIA RAG Retriever^active=true' -f 'sys_id,name,description,inputs' -o json

tool.nameLIKEAIA RAG Retriever dot-walks to the shared OOB tool definition's name (always "AIA RAG Retriever") — the returned name field is each match's own per-instance display name (e.g. "Semantic Knowledge Search"), not "AIA RAG Retriever" itself.

  • Matches found: Parse each tool's inputs (search profile, sources, fields, search type) and present them to the user. Ask whether to reuse an existing tool or create a new one — do not assume reuse or creation without the user's explicit choice.
  • Reusing an existing tool: Re-derive searchProfile, sources, fields, and semanticIndexes from a live query (see Profile Cascade below) rather than copying the stored inputs verbatim — the profile's state or indexes may have changed since the tool was created. If the live query disagrees with the stored inputs, the live result wins.
  • No matches, or user wants a new tool: Proceed to the Profile Cascade below.

Profile Cascade

Before creating a RAG tool, verify a published AI Search profile exists. The SDK does NOT create or publish profiles — profile lifecycle is the user's responsibility.

Query sequence to validate a profile:

  1. ais_search_profile — find active, published profiles (active=true^state=published)
  2. ais_search_profile_ais_search_source_m2m — get linked source sys_ids for the picked profile
  3. ais_search_source — get source records and their datasource table names
  4. ais_semantic_index_configuration — check for active indexes on those datasources
now-sdk query ais_search_profile -q 'active=true^state=published' -f 'sys_id,label,state' -o json
now-sdk query ais_search_profile_ais_search_source_m2m -q 'profile=<profile_sys_id>' -f 'sys_id,search_source' -o json
now-sdk query ais_search_source -q 'sys_idIN<linked_source_sys_ids>^active=true' -f 'sys_id,name,datasource' -o json
now-sdk query ais_semantic_index_configuration -q 'active=true^datasourceIN<table_names>' -f 'sys_id,name' -o json

Tier selection (internal logic — not user-facing labels):

ConditionSearch TypeAction
Published profile + active semantic indexeshybrid (default)Proceed
Published profile + no active indexeskeyword (forced)Inform user: no active indexes, falling back to keyword
No active published profiles[STOP]. Do NOT proceed until the user creates and publishes a profile

RAG Tool Inputs Format

All RAG inputs use ValueLabelType objects ({ value: string, label: string }) — NOT plain strings.

RAG Tool Example

{
name: 'Semantic Knowledge Search',
description: 'Searches knowledge articles using semantic search',
type: 'rag',
recordType: 'custom',
executionMode: 'autopilot',
preMessage: 'Performing semantic search...',
postMessage: 'Semantic search completed.',
inputs: {
searchType: {
type: 'semantic',
semanticIndexes: [
{ value: 'kb_knowledge_text_index', label: 'Knowledge Base Text Index' }
],
documentMatchThreshold: 0
},
searchProfile: {
value: 'quick_action_kb_search_profile',
label: 'Quick Action - KB Search Profile'
},
sources: [
{ value: 'kb_knowledge', label: 'Knowledge Articles' }
],
fields: [
{ value: 'kb_knowledge.short_description', label: 'Short description [kb_knowledge]' },
{ value: 'kb_knowledge.text', label: 'Article body [kb_knowledge]' },
{ value: 'kb_knowledge.number', label: 'Number [kb_knowledge]' }
],
searchResultsLimit: 5
}
}

Search Type Comparison

Propertykeywordsemantichybrid
searchType.type'keyword''semantic''hybrid'
semanticIndexesNot applicableRequiredRequired
documentMatchThresholdNot applicableAlways 0Always 0
searchProfileRequiredRequiredRequired
sourcesOptionalOptionalOptional
fieldsOptionalOptionalOptional
searchResultsLimitOptionalOptionalOptional

Important: documentMatchThreshold must always be set to 0. The field accepts [0, 1] but other values should not be used.


Execution Mode and Display

executionMode (copilot vs autopilot)

Each tool has its own executionMode that overrides the agent-level setting for that specific tool. Default: "autopilot".

Tool OperationSuggested executionModeWhy
CRUD lookup"autopilot"Read-only, no side effects
CRUD create"copilot"Creates records — user confirmation recommended
CRUD update"copilot"Modifies existing data
CRUD delete"copilot"Destructive, hard to reverse
Script (read-only)"autopilot"No side effects
Script (writes data)"copilot"Side effects — user confirmation recommended
Web Search"autopilot"Read-only external search
Search Retrieval (RAG)"autopilot"Read-only retrieval from AI Search indexes
Reference-based tools"copilot"Triggers flows/actions — confirmation recommended

General rule: Use "copilot" for tools that modify data or trigger external processes. Use "autopilot" for read-only operations. When unsure, prefer "copilot".

displayOutput

Controls whether tool output is shown to the user.

  • true — tool output is visible to the user
  • false — tool output is hidden (agent uses it internally)

maxAutoExecutions

Maximum number of times a tool can auto-execute without user confirmation. Default: 10. Only applies in copilot mode.

outputTransformationStrategy

Controls how tool output is transformed before the LLM processes it. Default: "none".

ValueBehaviorUse When
"none"No transformation — raw output passed throughOutput is already concise, or full data fidelity needed
"summary"Summarized into shorter formatVerbose output but key details must be preserved
"abstract_summary"Most minimal formatDefault for most tools — reduces output while retaining key points
"paraphrase"Rephrased in different wordsOutput needs rewording without significant data loss
"custom"Custom transformation using transformationInstructionsWhen custom transform logic is specified
"summary_for_search_results"Specialized summary for search resultsWeb Search or CRUD lookup tools returning many results

Selection guide by tool type:

Tool TypeSuggested StrategyWhy
CRUD lookup (few fields)"none"Output is already small
CRUD lookup (many fields/records)"none"Full data fidelity needed; instructions handle formatting
Web Search"none"Full results needed; agent instructions handle presentation
Script (returns structured data)"none"Preserve data accuracy
Tool feeding into another tool"abstract_summary"Reduce output volume for next tool to consume
Tool with user-facing output"abstract_summary"Concise output for users

Processing Messages

Every AiAgent MUST include processingMessage and postProcessingMessage as top-level properties. These are not available on AiAgenticWorkflow.

PropertyRequiredDescription
processingMessageYes (Agent)Shown to the user while the agent is working
postProcessingMessageYes (Agent)Shown to the user after the agent finishes

Generate context-appropriate messages based on the agent's purpose:

Agent PurposeprocessingMessagepostProcessingMessage
Incident management"Analyzing your incident request...""Incident analysis complete."
Knowledge search"Searching knowledge base...""Here are the results I found."
Record creation"Processing your request...""Your request has been completed."

Bad examples — do not use generic or uninformative messages:

Bad processingMessageWhy it's bad
"Processing..."Too generic, doesn't tell the user what's happening
"Please wait"No context about the operation
"Working on it"Uninformative

Every tool also supports preMessage and postMessage for tool-level status:

Tool ActionpreMessage ExamplepostMessage Example
CRUD lookup"Searching for incidents...""Incidents retrieved."
CRUD create"Creating the incident record...""Incident created successfully."
CRUD update"Updating the record...""Record updated successfully."
CRUD delete"Deleting the record...""Record deleted."
Script (compute)"Calculating results...""Calculation complete."
Web Search"Searching the web...""Search results retrieved."
Search Retrieval"Searching knowledge sources...""Documents retrieved."
Subflow/Action"Running the workflow...""Workflow completed."

Tool Composition

Composition Rules

ScenarioTools NeededWhy
Read/write database recordsCRUD onlyDirect table operations
Read records + calculate/transformCRUD + ScriptScript processes CRUD output
Read records + external infoCRUD + OOBWeb Search supplements DB data
Read, transform, and enrichCRUD + Script + OOBFull pipeline: fetch, process, enrich

Rules:

  • Each tool should do ONE thing — don't combine CRUD and computation in a single tool
  • Instructions must define the ORDER tools are used — the agent follows instruction steps
  • Name tools clearly so instructions can reference them unambiguously
  • Use outputTransformationStrategy on tools whose output feeds into other tools

Multi-Tool Instructions Pattern

When an agent has multiple tools, instructions must chain them explicitly:

Step 1: Gather Data.
- Use [CRUD Lookup Tool] to fetch records matching the user's criteria.
- NEVER skip this step — all subsequent steps depend on its output.
- DO NOT PROCEED if no records are found.

Step 2: Process Results.
- Use [Script Tool] to analyze/aggregate the data from Step 1.
- Present computed results to the user.

Step 3: Enrich (if needed).
- Use [OOB Web Search] to find supplementary information.
- Combine with Step 2 results and present the final summary before taking any action.

Troubleshooting

ProblemSolution
LOOKUP returns no dataAdd returnFields — it's MANDATORY
UPDATE runs but doesn't change any fieldsAdd mappedToColumn to all update inputs — without it, the update is a silent failure
UPDATE changes wrong fieldsVerify mappedToColumn values match actual column names from sys_dictionary
CRUD tool failsVerify recordType: "custom" and correct inputs ToolInputType format
Script failsCheck input parsing (parseInt, JSON.parse) and error handling
Permission issuesVerify user has necessary table/field access
OOB tool not workingVerify the tool type matches an OOB type (e.g., web_automation)
RAG returns no resultsVerify profile is active=true^state=published and semantic indexes are active

  • Building AI Agents Guide — full agent/workflow creation, authentication, triggers, ACL deployment
  • See the developing-apps-guide topic for project setup, authentication, and build workflow