Custom tools extend Candela with capabilities specific to your organisation - no code required for your end-users.
A tool wraps either of the following and exposes it as a named tool that your Candela agents can call:
A Scheduler job
For example, you could create a GetPortfolioProperties tool that returns all custom metadata attached to a portfolio, then assign it to a specialist agent so your team can retrieve that data through a simple conversation prompt.
This article explains how to create and assign custom tools via the LUSID Identity API.
Prerequisites
Suitable access permissions to create MCP tools in LUSID
For Luminesce tools: Your tested Luminesce SQL query
For Scheduler tools: Your Scheduler job’s scope and code
Step 1: Create a tool
Understanding the fields required to create a tool
All tools share the following fields:
Field | Description |
|---|---|
| A tool name that’s unique within your domain. |
| A friendly title to show in tool listings. |
| A specific, action-oriented description for the AI to use to decide when to call the tool. |
| Set to |
| Set to |
| A list of parameters that the tool can pass into the underlying Luminesce query or scheduler job. See parameters below. |
The query or job this tool executes; more information below. |
Note
The
idempotentandopenWorldfields are currently reference-only. In future, they will be used to govern how tools are executed and what external services they can access.
parameters
Each parameter declared in the parameters array can be referenced in your luminescePayload query or schedulerPayload arguments using triple curly brace {{{<parameter>}}} syntax. When called, Candela substitutes each placeholder with the value provided in the conversation.
Each parameter requires the following fields:
Field | Description |
|---|---|
| The parameter name, which you can subsequently reference in the payload as |
| The expected data type. |
| A specific description of the parameter for the agent to use to determine what value to pass. For example, |
Luminesce-powered tools
Imagine you want to create a tool that can run the following Luminesce query:
select [PropertyScope], [PropertyCode], [Value]
from [Lusid.Portfolio.Property]
where [PortfolioScope] = '{{{portfolioScope}}}' and [PortfolioCode] = '{{{portfolioCode}}}'You can call the CreateMcpTool API, passing in the fields from the table above, plus the following luminescePayload:
curl -X POST 'https://<your-domain>.lusid.com/identity/api/mcptools/Finbourne-Examples/GetPortfolioProperties'
-H 'Accept: application/json'
-H 'Authorization: Bearer <your-API-access-token>'
-H 'Content-Type: application/json-patch+json'
-d '{
"name": "GetPortfolioProperties",
"title": "Get custom properties for a portfolio",
"description": "Returns all custom properties attached to a portfolio. Use when the user asks about portfolio metadata, tags, or custom attributes.",
"destructive": false,
"idempotent": true,
"openWorld": false,
"readOnly": true,
"parameters": [
{ "name": "portfolioScope", "dataType": "String", "description": "The LUSID scope of the portfolio" },
{ "name": "portfolioCode", "dataType": "String", "description": "The LUSID code of the portfolio" }
],
"luminescePayload": {
"query": "select [PropertyScope], [PropertyCode], [Value] from [Lusid.Portfolio.Property] where [PortfolioScope] = '\''{{{portfolioScope}}}'\'' and [PortfolioCode] = '\''{{{portfolioCode}}}'\''"
}
}
'Scheduler-powered tools
To create a tool that can trigger a scheduled job, you can call the CreateMcpTool API, passing in the fields from the table above, plus the following schedulerPayload:
curl -X POST 'https://<your-domain>.lusid.com/identity/api/mcptools/Finbourne-Examples/RunComplianceJob'
-H 'Accept: application/json'
-H 'Authorization: Bearer <your-API-access-token>'
-H 'Content-Type: application/json-patch+json'
-d '{
"name": "RunComplianceJob",
"title": "Run a compliance scheduler job",
"description": "Triggers the nightly compliance job for a given set of rules.",
"destructive": false,
"idempotent": false,
"readOnly": false,
"parameters": [
{
"name": "ruleScope",
"dataType": "String",
"description": "The rules scope to run compliance on"
},
{
"name": "runScope",
"dataType": "String",
"description": "The scope to run compliance for"
}
],
"schedulerPayload": {
"jobScope": "Finbourne-Examples",
"jobCode": "RunCompliance",
"arguments": {
"ruleScope": "{{{ruleScope}}}",
"runScope": "{{{runScope}}}"
}
}
}'Step 2: Assign the tool to an agent
Agents only call tools that you explicitly list in their toolNames array. See how to create or update an agent.