Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.useterse.ai/llms.txt

Use this file to discover all available pages before exploring further.

Integrations and skills are two sides of the same coin. An integration is a connected external service: your CRM, enrichment provider, messaging tool, or data warehouse. A skill is the declaration that hands an integration to your workflow. Connect once, generate typed code, then declare per job which skills the model can reach.

Integrations: stored credentials

An integration is a connection to an external service. When you run terse integrate or connect through the Terse app, the platform stores your OAuth tokens or API keys securely. The integration itself is just an authenticated link to a service. Terse supports two connection types:
TypeFlowExamples
OAuthOpens your browser for authorizationGitHub, Slack, Gmail, Linear, Notion, Attio
FormPrompts for API keys or account credentials in the terminalDatadog, PostHog, Snowflake, LaunchDarkly, WorkOS
After connecting, run terse generate to turn your active integrations into typed code.

Code generation: from credentials to code

terse generate reads your connected integrations and their resources (repos, channels, lists, teams, projects), then writes a typed SDK file for your project. See the Generated SDK page for more detail.

Skills vs. deterministic tools

This is the key distinction:
Skills (model access)Deterministic tools (code access)
Who decidesThe model chooses which tools to callYour code calls tools directly
Controlled byskills array on generateText (or TerseAgent.create())toolbox.* (unfiltered)
ScopeOnly integrations declared as skillstoolbox.* covers any connected integration
Token costTokens consumed per callZero LLM tokens
agent.tools.* mirrors the skills allowlist: only integrations declared as skills appear on the agent’s typed tool object. For unfiltered programmatic access to every connected integration, import toolbox from ./terse.generated and call it directly, no agent needed. This means you can be precise about the model’s reach for a given job, while still calling any connected integration from your handler code through toolbox:
import { generateText, createJob } from "terse-sdk"

import { AttioObject, Skills, SlackChannel, Triggers, toolbox } from "./terse.generated"

createJob({
    name: "weekly-digest",
    triggers: [Triggers.schedule.cron({ expression: "0 9 * * 1" })],
    onTrigger: async (event) => {
        // Agentic: model can only use Attio (the declared skill)
        const summary = await generateText({
            prompt: "Summarize this week's pipeline activity.",
            skills: [Skills.attio({ object: AttioObject.Deal })]
        })

        // Deterministic: toolbox is unfiltered, so Slack works even though it isn't a skill
        await toolbox.slack.sendMessage({
            channelId: SlackChannel.DealDesk.channelId,
            message: summary
        })
    }
})

Skill configuration

Some skills accept configuration that scopes what the model sees or where it acts:
SkillConfigurationEffect
Skills.attio()objectScopes record reads and writes to one Attio object
Skills.slack()channelTargets a specific channel for messaging
Skills.github()reposScopes code access to specific repositories
Skills.linear()team, projectOptionally scopes to a team and/or project
Skills.snowflake()NoneRead-only SQL queries against your warehouse
Skills.web()NoneBuilt-in web search, page extraction, and research
Skills without configuration give the model access to the full integration surface.

Where to go next

Skills & tools reference

Full list of every skill and the tools it exposes.

Deterministic tool calls

Call tools directly from code without the LLM.