Configure Capabilities
Set up what your agent code is allowed to do.
Before your LLM writes any code, you need to decide what that code will be allowed to do. In Qosm, this means configuring capabilities — typed functions that the host (you) provides to the agent.
Think of it this way: instead of giving the agent a set of permissions and hoping it stays within bounds, you give it a set of functions and the compiler guarantees it can't call anything else.
The workspace capabilities panel
Go to your workspace, open a project, and look at the Capabilities panel on the left. This is where you configure what your code can do.
There are four base capability types:
| Capability | What it provides | Effect |
|-----------|------------------|--------|
| model | LLM inference with structured output | LLM.Call |
| http_get | HTTP GET requests, scoped to a domain | Http.Get |
| http_post | HTTP POST requests, scoped to a domain | Http.Post |
| log | Write to the project log | Log.Write |
You can also connect MCP servers (external tools) and OpenAPI specs (API endpoints) — these become capabilities too. We'll cover that in Code Mode.
Create a model capability
Let's set up an LLM:
- Click + next to "model"
- Name it
my_claude— this becomes the function name in your code - Select Anthropic as the API type
- Enter your API key
- Click Create
Your code can now call my_claude as a function. The API key is stored on the server — agent code never sees it.
Create an HTTP capability
Now let's add the ability to call an API:
- Click + next to "http_get"
- Name it
api_get - Set the allowed domain to
api.example.com - Optionally configure authentication (Bearer, API key, etc.)
- Click Create
The code can now call api_get — but only to api.example.com. The domain restriction is enforced by the runtime. The authentication credentials are injected automatically and never appear in your code.
What this looks like to the code
When you enable capabilities, the workspace generates extern declarations that are prepended to your code:
effect LLM.Call;
extern my_claude : String -> Result<'a, QosmError> ! {LLM.Call};
effect Http.Get;
extern api_get : {url: String, headers: Array<{key: String, value: String}>}
-> Result<String, QosmError> ! {Http.Get};
These declarations are the capability manifest. The compiler only allows your code to call functions that appear here. If you try to use http_post without creating a capability set for it, the compiler will reject the code with "unbound identifier."
This is what makes Qosm different from sandboxing or RBAC: the security boundary isn't a runtime check — it's a compile-time guarantee.
Now let's write some code.