Connect ConnectWise PSA to AI Agents: Automate Procurement and Stock
Learn how to connect ConnectWise PSA to AI agents using Truto's /tools endpoint. Automate procurement, stock, and ticket workflows with native tool calling.
You want to connect ConnectWise PSA to an AI agent so your system can independently audit stock levels, generate purchase orders, resolve IT service tickets, and log billing time against specific agreements. Here is exactly how to do it using Truto's /tools endpoint and SDK, bypassing the engineering bottleneck of hand-rolling API wrappers.
Giving a Large Language Model (LLM) read and write access to your managed service provider (MSP) infrastructure is an engineering headache. You either spend months building, hosting, and maintaining a custom connector, or you use a managed infrastructure layer that handles the boilerplate for you. If your team uses ChatGPT, check out our guide on connecting ConnectWise PSA to ChatGPT, or if you are building on Anthropic's models, read our guide on connecting ConnectWise PSA to Claude. For developers building custom autonomous workflows, you need a programmatic way to fetch these tools and bind them directly to your agent framework.
This guide breaks down exactly how to fetch AI-ready tools for ConnectWise PSA, bind them natively to an LLM using frameworks like LangChain, LangGraph, CrewAI, or the Vercel AI SDK, and execute complex procurement workflows. For a deeper look at the architecture behind this approach, refer to our research on architecting AI agents and the SaaS integration bottleneck.
The Engineering Reality of Custom ConnectWise PSA Connectors
Building AI agents is easy. Connecting them to external SaaS APIs safely is hard. Giving an LLM access to external data sounds simple in a prototype: you write a Node.js function that makes a fetch request and wrap it in an @tool decorator. In production, against an enterprise API like ConnectWise PSA, this approach collapses entirely.
If you decide to build a custom integration for ConnectWise PSA, you own the entire API lifecycle. ConnectWise PSA introduces several specific integration challenges that break standard LLM assumptions.
The Highly Relational Object Model
ConnectWise PSA is heavily normalized. Almost nothing exists in isolation. A service ticket is tied to a specific board, which is tied to a company, which has a specific site, which references a contact. When an AI agent wants to "check the configuration for the server reported in Ticket #1024," it cannot simply read a flat JSON object. It must traverse the Ticket object to find the Company ID, hit the Configurations endpoint filtering by that Company ID, and match the device identifier.
If you hand-code these tools, you are responsible for writing massive JSON schemas instructing the LLM on exactly how to chain these relational IDs. Truto maps these endpoints into standard Proxy APIs, returning structured tool definitions that implicitly guide the LLM on which IDs are required for subsequent calls.
Procurement State Constraints
The ConnectWise PSA Procurement API is exceptionally strict regarding state transitions. You cannot simply create a Purchase Order and instantly mark it as "received." You must navigate through generating a PO, attaching PO Line Items that reference specific Catalog Items, updating the PO status, managing shipping and picking details, and converting inventory. AI agents are notoriously bad at guessing rigid finite state machines. By exposing specific Proxy API methods (like update_a_connect_wise_psa_procurement_purchaseorder_by_id), the LLM is restricted to the available state transitions defined in the schema, preventing hallucinated API calls.
Handling Rate Limits the Right Way
When an AI agent runs a loop over a large ConnectWise PSA instance—say, auditing 500 configurations for an expiring warranty—it will quickly exhaust upstream API rate limits.
A critical architectural fact: Truto does not retry, throttle, or apply backoff on rate limit errors automatically. When the ConnectWise PSA API returns an HTTP 429 (Too Many Requests), Truto passes that exact error back to the caller. Truto normalizes the upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification.
This is an intentional design decision. In an agentic workflow, the caller (your application or agent framework) must maintain control over the execution loop. If the infrastructure absorbed the retry silently, it would block the agent's execution thread unpredictably, causing timeouts and broken reasoning chains. The caller is responsible for reading the ratelimit-reset header, pausing the agent, and executing a retry/backoff strategy.
Generating AI-Ready Tools for ConnectWise PSA
Instead of manually writing OpenAPI specs or Zod schemas for the ConnectWise PSA API, you can use Truto's /tools endpoint. Truto translates the integration's underlying methods into a standardized array of tools formatted for LLM consumption.
To fetch these tools, you make a single API call to your integrated ConnectWise PSA account:
// Fetching tools via Truto's API
const TRUTO_API_KEY = process.env.TRUTO_API_KEY;
const INTEGRATED_ACCOUNT_ID = process.env.CONNECTWISE_ACCOUNT_ID;
const response = await fetch(
`https://api.truto.one/integrated-account/${INTEGRATED_ACCOUNT_ID}/tools?methods[0]=read&methods[1]=write`,
{
headers: {
Authorization: `Bearer ${TRUTO_API_KEY}`,
Accept: "application/json",
},
}
);
const tools = await response.json();
// 'tools' is now an array of schema-defined functions ready to be bound to your LLM.If you are using LangChain, Truto provides a dedicated SDK (truto-langchainjs-toolset) that handles this fetching and binding natively.
ConnectWise PSA Hero Tools for AI Agents
Truto exposes the entirety of the ConnectWise PSA API as tools. However, when automating MSP and procurement operations, certain tools provide the highest leverage. Here are the hero tools your agent will use most often.
1. list_all_connect_wise_psa_inventory_on_hands
This tool allows the agent to check current stock levels across all warehouses and bins. It is essential for determining if a part requested in a service ticket is available or needs to be ordered.
"Check the inventory for catalog item 'Cisco Meraki MX64'. Which warehouse currently has stock on hand, and what are the serial numbers?"
2. create_a_connect_wise_psa_procurement_purchaseorder
When inventory is low, the agent uses this tool to generate a new Purchase Order shell. It handles the relational mapping of the vendor, business unit, and shipping destinations.
"We need more SSDs. Draft a new Purchase Order for Vendor ID 842. Set the shipping destination to the primary warehouse and leave the status as 'Open'."
3. create_a_connect_wise_psa_purchaseorder_lineitem
After creating a PO shell, the agent uses this tool to attach specific products, quantities, and expected costs to the order.
"Add a line item to Purchase Order #5091 for 25 units of catalog item 'Samsung 1TB SSD' at a unit cost of $85.00."
4. list_all_connect_wise_psa_tickets
The gateway to the service board. The agent uses this to find open issues, filter by company, or search for tickets assigned to specific engineers.
"Find all high-priority tickets on the 'Network Infrastructure' board that have been open for more than 48 hours without an update."
5. create_a_connect_wise_psa_time_entry
Autonomous agents should log their own work. This tool allows the agent to create a time entry against a specific ticket, agreement, or project, ensuring accurate billing for automated resolutions.
"I just resolved the DNS routing issue for Ticket #9932. Log 15 minutes of time against this ticket under the 'Automated Remediation' work role, and mark it as billable."
6. list_all_connect_wise_psa_company_configurations
Configurations are the lifeblood of an MSP. This tool lets the agent look up specific devices, their MAC addresses, warranty expiration dates, and installed OS versions based on the client.
"Pull all configurations for Company 'Acme Corp' and identify any servers where the warranty expiration date has passed."
To view the complete inventory of available ConnectWise PSA tools—including advanced billing, RMA, and workflow endpoints—visit the ConnectWise PSA integration page.
Workflows in Action
Individual tools are useful, but AI agents unlock exponential value when chaining these tools together to resolve complex intents. Here is how a multi-step agent navigates ConnectWise PSA.
Scenario 1: Autonomous Hardware Procurement
An IT admin asks the agent to secure equipment for a new hire.
"Acme Corp is onboarding a new developer next week. Check if we have a 'MacBook Pro M3' in the main warehouse. If not, generate a Purchase Order from our primary Apple distributor for one unit and associate it with Acme Corp's onboarding ticket #8812."
Execution Steps:
- Inventory Check: The agent calls
list_all_connect_wise_psa_inventory_on_handsfiltering for the specific catalog item. It parses the response and seesonHand: 0. - PO Creation: The agent calls
create_a_connect_wise_psa_procurement_purchaseorder, associating the customer company (Acme Corp) and setting the business unit to Procurement. - Line Item Addition: The agent extracts the new
purchaseOrderIdand callscreate_a_connect_wise_psa_purchaseorder_lineitemto add 1 unit of the MacBook Pro. - Ticket Update: Finally, the agent calls
create_a_connect_wise_psa_ticket_noteon Ticket #8812, logging that the hardware is out of stock and PO #5092 has been generated.
Scenario 2: Warranty Audit and Upsell Generation
An account manager wants to proactively manage client infrastructure.
"Audit the configurations for 'Globex Inc'. Find any firewalls where the warranty expires in the next 30 days. For each one, create a sales opportunity to renew the hardware warranty."
Execution Steps:
- Fetch Configurations: The agent calls
list_all_connect_wise_psa_company_configurations, filtering for Globex Inc and configuration types matching "Firewall". - Evaluate Data: The LLM compares the
warrantyExpirationDateof the returned objects against the current date. - Opportunity Creation: For the matching records, the agent loops through
create_a_connect_wise_psa_sales_opportunity, attaching the specific configuration ID to the notes and setting the stage to "Initial Contact".
Building Multi-Step Workflows
To build these workflows in code, you need an orchestration layer that handles the agent loop. Below is a conceptual example using LangChain.js and Truto's SDK. This pattern applies equally to LangGraph or the Vercel AI SDK.
The key engineering requirement here is handling errors—specifically HTTP 429 Rate Limits. Because Truto passes rate limits directly to the caller, your execution loop must intercept these errors and apply a backoff strategy before allowing the agent to continue.
import { ChatOpenAI } from "@langchain/openai";
import { AgentExecutor, createOpenAIToolsAgent } from "langchain/agents";
import { TrutoToolManager } from "truto-langchainjs-toolset";
import { pull } from "langchain/hub";
import { ChatPromptTemplate } from "@langchain/core/prompts";
async function runProcurementAgent(prompt: string) {
const llm = new ChatOpenAI({
modelName: "gpt-4o",
temperature: 0,
});
// 1. Initialize the Truto Tool Manager
const trutoManager = new TrutoToolManager({
apiKey: process.env.TRUTO_API_KEY,
});
// 2. Fetch specific ConnectWise PSA tools
const tools = await trutoManager.getTools(
process.env.CONNECTWISE_ACCOUNT_ID,
{
methods: ["read", "write", "custom"],
}
);
// 3. Bind tools to the prompt and LLM
const promptTemplate = await pull<ChatPromptTemplate>("hwchase17/openai-tools-agent");
const agent = await createOpenAIToolsAgent({
llm,
tools,
prompt: promptTemplate,
});
const executor = new AgentExecutor({
agent,
tools,
// Important: Do not silently drop errors. We need to catch 429s.
returnIntermediateSteps: true,
});
try {
// 4. Execute the workflow
const result = await executor.invoke({
input: prompt,
});
console.log("Workflow Complete:", result.output);
} catch (error: any) {
// 5. Handle Rate Limits Explicitly
if (error.status === 429) {
const resetSeconds = error.headers.get('ratelimit-reset') || 60;
console.warn(`Rate limit hit. Agent execution paused for ${resetSeconds} seconds.`);
// Implement your application-level pause/queue logic here
// await sleep(resetSeconds * 1000);
// return runProcurementAgent(prompt);
} else {
console.error("Agent Execution Failed:", error);
}
}
}
runProcurementAgent(
"Check stock for Catalog Item 'RAM-16GB'. If zero, create a PO for 10 units."
);The Architecture Behind the Loop
When the agent decides to execute a tool, the framework serializes the LLM's JSON output and makes a request to Truto's Proxy API.
sequenceDiagram
participant App as Your App (Agent)
participant Truto as Truto API
participant CW as ConnectWise PSA
App->>Truto: Call create_purchaseorder(payload)
Truto->>CW: POST /procurement/purchaseorders
alt Success
CW-->>Truto: 201 Created (PO Data)
Truto-->>App: JSON Response
App->>App: LLM analyzes PO ID, plans next step
else Rate Limit Exceeded
CW-->>Truto: 429 Too Many Requests
Truto-->>App: 429 (Headers: ratelimit-reset)
Note over App: App pauses execution<br>Retries after reset
endBy keeping the integration layer thin and declarative, Truto ensures that your agent receives predictable, strongly-typed responses. You avoid writing thousands of lines of TypeScript to handle OAuth refresh flows, XML/JSON parsing discrepancies, and vendor-specific authentication headers.
Moving from Scripts to Autonomous Systems
Connecting ConnectWise PSA to AI agents transforms your MSP from a reactive service provider into a proactive, autonomous system. Instead of engineers manually clicking through boards to order parts, verify warranties, or check inventory, agents can run these workflows in the background triggered by webhooks or natural language chat.
The bottleneck to building these systems has always been the integration layer. Hand-rolling a ConnectWise PSA client that can safely handle relational constraints and rate limits takes weeks of dedicated engineering time. By using Truto's unified tools endpoint, you abstract away the API mechanics and focus entirely on the agent's prompt engineering and business logic.
FAQ
- How does Truto handle ConnectWise PSA API rate limits?
- Truto does not automatically retry or apply backoff on rate limits. When ConnectWise PSA returns an HTTP 429, Truto passes the error back to the caller, normalizing the details into standard IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). The caller is responsible for the retry strategy.
- Can I use Truto's ConnectWise PSA tools with LangChain?
- Yes. Truto provides a dedicated truto-langchainjs-toolset SDK that seamlessly fetches tools from the /tools endpoint and formats them for immediate use with LangChain's .bindTools() method.
- Does Truto support custom fields in ConnectWise PSA?
- Yes. Truto exposes ConnectWise PSA resources dynamically, meaning any custom user-defined fields (UDFs) present in the integrated account's schema are accessible by the AI agent.
- Do I have to write the tool schemas manually?
- No. Truto automatically generates the tool definitions, descriptions, and JSON schemas directly from the underlying Proxy API definitions, saving you from writing and maintaining massive Zod or OpenAPI schemas.