An asset provider connects an external service to Daslab: the resources the service holds become typed, browseable assets, and the tools an agent uses on them ship in the same folder. There is no SDK and no build step. A provider is a JSON manifest, plain tool files, and an HTML view:
providers/polyhaven/
├── provider.json # identity, asset types, tools, views
├── tools/
│ ├── polyhaven_search.ts
│ ├── polyhaven_files.ts
│ ├── polyhaven_info.ts
│ └── browse.ts # feeds the visual asset picker
└── views/
├── preview.html # how a pinned asset draws itself
└── preview.fixture.json
Most integration formats describe functions. This one also describes the things the functions work on. Every asset type declared in the manifest appears in Daslab's asset picker, so a person can find a resource by name instead of the agent guessing ids.
The polyhaven example makes this concrete. It declares three asset types over Poly Haven's CC0 library: HDRIs, PBR textures, and 3D models, about 2,300 in all. In Daslab you search the picker for "concrete floor" and pin the texture into a scene. Every workflow becomes a scene — its data, its tools, the agent that runs it, and the history of everything it did. The pinned texture carries the fields the provider declared (slug, tags, resolution), draws itself through the provider's view, and when the agent needs the actual image maps, polyhaven_files resolves the download URLs. No key is needed anywhere in that path.
| Provider | Auth | Shows |
|---|---|---|
timezone |
none | The minimal provider: one code tool, one live clock view |
brave |
api_key | A provider in one file: a single http_call tool with the credential templated into a header |
polyhaven |
none | The full asset model: three types, searchable browse, typed fields, display templates, one view per type |
polymarket |
none | Hierarchy: markets nest under events, browse with search, a market view that fetches live odds |
passkeytest |
none | Passkey-gated vault: user generates a WebAuthn passkey in the view; Daslab stores ciphertext only; tools cannot decrypt |
All five pass the validator and load into a Daslab server unchanged.
Start from the example closer to what you're building and rename the folder. The manifest spec covers every field; the short path:
- Declare identity and auth in
provider.json. The format covers API-key and keyless services; OAuth is not expressible in it. - Declare your resource types with their fields and display templates.
- Write the tools. Use
http_callwhen a tool is one HTTP request: it is declarative, and a reviewer can read it at a glance. Use acodebody when you need logic; each body is a self-contained file that readsctx.inputand returns a value. - Add one tool with
role: "browse"so the asset picker has something to show. - Give your types a view: an HTML file that reads
window.__ASSET__, next to a fixture of mock fields for previewing it.
Then check your work:
bun cli/validate.ts providers/yourprovider
bun cli/run.ts providers/yourprovider yourprovider_search '{"query":"test"}'The validator checks the manifest, the entry files, and the naming rules, and tells you exactly what's missing. The runner executes one tool locally against the real API, under the same contract the server runs it with; pass --credential api_key=... when the provider needs one.
Providers merged here ship in Daslab as community integrations, which is why review is strict: a merged provider runs with the same standing as one we wrote. Prefer http_call impls, which can be audited at a glance. A code body gets read line by line: keep it self-contained, and let errors throw rather than swallowing them.
MIT licensed.