← All help articles

Agent Access (AI Support & Automation)

What is it?

Programs (the AI support assistant, your own automations, third-party systems) can access a limited, clearly defined set of functions in your organization — the "tool layer" — without logging in as a human. The same access also authenticates the REST API (/api/v1/projects, /api/v1/test-cases, …).

There are two ways in:

  • Sign in with OAuth (for AI assistants like Claude, ChatGPT, Cursor or VS Code): you enter just the address, sign in in your browser and approve. You set this up yourself, no token needed — see "Connecting via MCP" below.
  • Agent token (for automations without a person in front, e.g. scripts or servers): a fixed token in a header. We set these tokens up for you — there's no screen to issue them yourself yet; contact our team.

How it works

  • Permissions: Every programmatic access runs through the same permission model as a human member and only ever sees your own organization.
  • Traceable: Every action is logged in the audit log with actor type Agent — with OAuth, also with the person the app acts on behalf of.

Available tools (read-only)

  • search_docs — searches this help documentation.
  • get_org_overview — key figures (projects, stations, test objects, …).
  • get_calibration_status — equipment calibrations due/overdue.
  • list_recent_audit_events — recent changes (admin role only).
  • get_webhook_deliveries — webhook delivery attempts (admin role only).
  • get_ingestion_deliveries — measurement deliveries (REST/MQTT) with success/failure per station.
  • get_report_status — current report status and stored failure reason, optionally filtered by report or project.
  • get_capacity_forecast — capacity forecast per station type (utilisation, peak load, backlog, missing stations), optionally as a what-if; saves nothing (see Capacity forecast).

Connecting via MCP (Model Context Protocol)

TestLabIQ ships a built-in MCP server. MCP is an open standard — the server isn't tied to any particular AI vendor. Any client that speaks the Streamable HTTP MCP transport works.

Address: https://app.testlabiq.com/api/v1/agent/mcp

Recommended: sign in with OAuth

Enter just the address in your AI client. The first time it connects, the client opens a browser window:

  1. You sign in to TestLabIQ as usual.
  2. You see which app wants access and where you'll be sent afterwards.
  3. You choose the organization and what the app may do: Read only, Read and edit or Manage — at most your own role.
  4. Click Allow and the app is connected.

From then on, the app acts on your behalf: the audit log shows each action as Agent — on behalf of you. It can never do more than you: if your role is lowered or you leave the organization, that applies to the app immediately. Under Settings → My settings → Connected apps you see every connection with its last use and can disconnect any of them instantly.

In common clients:

  • Claude (web, desktop, mobile) and ChatGPT: add a custom connector (in ChatGPT, in developer mode) and enter the address above as the URL. Authentication: OAuth.

  • Claude Code:

    claude mcp add -s user --transport http testlabiq https://app.testlabiq.com/api/v1/agent/mcp
    

    then run /mcp in a session and choose "Authenticate".

  • Cursor (~/.cursor/mcp.json):

    { "mcpServers": { "testlabiq": { "url": "https://app.testlabiq.com/api/v1/agent/mcp" } } }
    
  • VS Code / GitHub Copilot (.vscode/mcp.json or "MCP: Open User Configuration"):

    { "servers": { "testlabiq": { "type": "http", "url": "https://app.testlabiq.com/api/v1/agent/mcp" } } }
    
  • Other clients: enter the address; if the client supports OAuth for MCP servers, sign-in starts on its own. It discovers our authorization server automatically (RFC 9728/8414 metadata) and registers itself (Dynamic Client Registration) — nothing else to configure.

The server name you enter in the client (testlabiq above) is up to you. For several organizations, simply connect the app several times — you choose one organization per connection.

Alternative: agent token in a header

For automations without a person in front (scripts, servers, CI) there's the fixed agent token. Send it in the x-agent-token header (or Authorization: Bearer <token>); no browser sign-in involved.

Claude Code:

claude mcp add -s user --transport http testlabiq \
  https://app.testlabiq.com/api/v1/agent/mcp \
  -H 'x-agent-token: ${TESTLABIQ_TOKEN}'

Use single quotes so your shell doesn't expand the variable — the placeholder is stored and resolved on every connection.

Cursor: as above, plus "headers": { "x-agent-token": "${env:TESTLABIQ_TOKEN}" }.

VS Code: as above, plus "headers": { "x-agent-token": "${input:testlabiq-token}" } and a matching "inputs" entry ("type": "promptString", "password": true) — VS Code then prompts for the token once and stores it encrypted.

Codex CLI (~/.codex/config.toml):

[mcp_servers.testlabiq]
url = "https://app.testlabiq.com/api/v1/agent/mcp"
bearer_token_env_var = "TESTLABIQ_TOKEN"

Your own agents with the official MCP SDK (TypeScript):

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(
  new StreamableHTTPClientTransport(new URL("https://app.testlabiq.com/api/v1/agent/mcp"), {
    requestInit: { headers: { "x-agent-token": process.env.TESTLABIQ_TOKEN! } },
  }),
);
const { tools } = await client.listTools();

In Python: streamablehttp_client(url, headers={"x-agent-token": token}).

Testing the connection without a client (agent token)

curl -s https://app.testlabiq.com/api/v1/agent/mcp \
  -H "x-agent-token: $TESTLABIQ_TOKEN" \
  -H "content-type: application/json" \
  -H "accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

If you get a list of tools back, your access works and any remaining issue is in the client configuration. A 401 means the token is missing, wrong or revoked.

Which organization applies?

Not selectable per call, on purpose: no tool takes an organization as a parameter, so even a manipulated instruction to the AI can't redirect it.

  • With OAuth you choose the organization when approving; it applies to that one connection.
  • An agent token is bound to exactly one organization when it's issued. To work with several organizations, get one token per organization and set up one MCP connection per token (e.g. testlabiq-lab-north, testlabiq-lab-south).

Common issues

  • "I can't find a page to create or revoke a token." AI assistants don't need one — connect via OAuth (see above) and disconnect under Connected apps. We set up fixed agent tokens for automations; contact our team for that or if something looks off.
  • "The client says 'needs authentication' / offers a sign-in." With OAuth, that's the normal first step — start the sign-in. If you configured an agent token, it's missing or invalid (often the environment variable isn't set in the environment the client starts from; many clients don't read .env files).
  • "My organization is greyed out on the approval page." Agent access is turned off for that organization (kill switch). Ask an administrator.
  • "I can only pick 'Read only'." An app gets at most your own role.
  • "The app was connected and is suddenly signed out." Possible reasons: you (or the app itself) disconnected it; you're no longer a member of the organization; or the app sent an already-used refresh token a second time — we treat that as possible theft and disconnect as a precaution. The reason is in the audit log ("AI app disconnected"). Just connect again.
  • "401 / Invalid token." The configured token is wrong or has been revoked — or, with OAuth: the connection was disconnected or agent access for the organization was turned off.
  • "403 / Permission denied." The configured access isn't allowed to use this tool. The diagnostic tools for audit and webhooks require admin rights.
  • "The agent sees data from another organization." This can't happen: every access is bound to exactly one organization, and tenant isolation applies here too at the database level.

Still have questions?

We're happy to show you TestLabIQ live – with your own use cases.

Book a demo