What does this customer pay for these four products, and which suppliers
carry them?
That is a question of a few seconds and still half an hour of work. Someone clicks through the accounting package from customer to price list to product, four times in a row, and copies the answer into an email. We built a client a connection that lets the same question be asked in plain language, directly in a chat with Claude. Here is what we learned, and what you can take from it if you want something similar.
The client stays anonymous and there are no amounts, prices or margins here. This is about the build.
Not the accounting system itself, but a copy
The first choice was the most important one: the assistant does not talk to the accounting package, it talks to our own copy of the data, which we refresh at night. There are three reasons for that.
Speed. A question about customer prices touches a handful of separate requests in the package itself. On our own copy it is a single query.
Limits. The accounting package enforces a cap on the number of calls per minute and per day. A curious assistant reaches that cap surprisingly fast. On a copy, a curious question bothers nobody.
Calm. Filling that copy the first time meant thousands of lines of price agreements, spread over dozens of price lists. You want to do that once and then only fetch the changes. That is exactly what happens now.
Read only, and able to prove it
The connection cannot change anything. Not because we could not build it, but because the owner of an administration does not want an assistant that accidentally edits a price.
Read only is easy to say. We pinned it down in three ways. The connection exists only in the production environment; the development environment works on a copy with no link to the package at all. There is a test in the project that fails as soon as code appears that could write. And the account we connect with has read only rights itself.
That last point is one to remember if you do this yourself: in many accounting packages a connection inherits the rights of the person who switches it on. If the owner connects, the connection may do everything the owner may do. So create a separate user with only the rights that are needed, and connect with that user.
Signing in without handing out keys
The assistant comes in through the standard that exists for this, with a sign in step in the browser and an access token that expires. No fixed key in a settings file, no password travelling through a chat. A separate access per administration, so someone allowed to work on one administration cannot look into the other.
One trap cost us an afternoon and was in no manual: the package refused to renew the access token while the old one was still valid for a while. Renew too early and you get an error that looks like a permissions problem. The fix is to renew just before it expires, with a small margin. And: put a weekly job on it, so the token itself does not expire during a quiet week.
The lesson we did not expect
When the first user started testing, we read along in the log. He asked for the price of four products for one customer. The assistant made seven separate requests for that, neatly one at a time.
Technically that was right. It had the function "price of product X for customer Y" and used it as often as needed. But it was slow and hard to read. The fix was not in the assistant and not in the model: we had offered the wrong function. We added one that handles several products at once, and the question became a single request.
That is the main lesson of this project. You do not design a connection for an assistant the way you design one for a program. You look at the questions people ask, and you turn those into one function. Seven times the right answer is still the wrong design.
What it can do now
Five things, and that is deliberately few: find a product, the price of one or more products for a given customer, the best customers over a period, look up orders, and the suppliers of a product. Each of those is a question that used to be clicking.
What it cannot do matters just as much: book, invoice, change prices. That stays manual work in the package itself, with a person pressing send.
Common mistakes
Connecting with the owner's account. Then the connection may do everything. Create a separate user with read only rights.
Enabling the connection in your development environment too. Then it is a matter of time before a test writes something into the real administration. Let the development environment work on a copy.
Building one function per field. You end up with an assistant that makes ten requests in a row. Build the function that answers the question, not the function that matches your database.
Trusting that the manual is correct. For us the behaviour of the package differed from the documentation on several points. Log the answers you get back, certainly in the first week.
Building in no limit of your own. An assistant that is allowed to keep asking will keep asking. Put your own cap on the number of requests per chat, before the package does it for you.
Building something like this for your own administration or package falls under custom software. If you are unsure whether it fits, we will look at it with you before you build anything; see AI consultancy.