Artificial intelligence is becoming part of everyday software development, including project management, collaboration, and workflow automation. Applications built on Atlassian Forge can now use large language models without managing a separate model hosting environment or sending application data to an external AI provider.

The Forge LLMs API allows developers to call Atlassian-hosted language models directly from Forge applications. It provides a common interface for generating responses, processing user prompts, streaming output, and building AI-powered workflows.

For developers building Jira and Confluence applications, this removes several integration challenges. There is no need to manage an external model API key or independently deploy model infrastructure for supported Forge LLM requests.

In this article, we will explore how the Forge LLMs API works, how to configure it in a Forge application, and how to build a practical AI-powered Jira feature using the @forge/llm SDK.

What Is the Atlassian Forge LLMs API?

The Forge LLMs API is a platform capability that allows Forge applications to interact with large language models hosted by Atlassian.

Previously, developers commonly integrated AI features by connecting their Forge applications to external providers. This required API credentials, external network permissions, provider-specific SDKs, and additional data-handling considerations.

The hosted LLM API provides an alternative.

A Forge application can send a prompt to a supported model through the Forge runtime and receive the generated response.

The main capabilities include:

  • Chat-based interactions with language models.
  • Streaming responses for incremental output.
  • Multi-turn conversations using message history.
  • Function calling through tool definitions.
  • Model selection based on application requirements.
  • Token usage information for monitoring consumption.

The API currently supports Anthropic Claude model families. Developers can check the available models and their status through the SDK rather than assuming that every model is available permanently.

One important advantage is that requests remain within Atlassian-managed infrastructure. Apps using Forge LLMs can retain eligibility for the Runs on Atlassian badge, provided they meet the other applicable requirements.

Understanding the Forge LLM Architecture

A typical Forge application contains a frontend, backend functions, and Atlassian platform services.

The LLM integration usually happens in a backend function rather than directly in the browser.

Consider an AI assistant that summarizes Jira issues.

The workflow looks like this:

Code
Jira User Interface
        |
        v
Forge Frontend
        |
        v
Forge Backend Function
        |
        v
@forge/llm SDK
        |
        v
Atlassian Hosted LLM
        |
        v
Generated Response
        |
        v
Forge Frontend
        |
        v
Display Summary

Each component has a specific responsibility.

The frontend collects the user's request and displays the generated response.

The backend retrieves the necessary Jira information and prepares the prompt.

The Forge LLM SDK sends the request to the selected hosted model.

The model generates a response, which the backend validates before returning it to the frontend.

Keeping this integration on the backend also helps prevent unnecessary exposure of application data and business logic.

Prerequisites for Building a Forge LLM Application

Before implementing the integration, prepare the following:

  • An Atlassian developer account.
  • Access to a Jira or Confluence development site.
  • Forge CLI installed on your development machine.
  • Node.js compatible with the current Forge development environment.
  • Basic knowledge of JavaScript or TypeScript.
  • Familiarity with Forge modules and application manifests.

You should also understand how Forge functions communicate with the frontend.

Step 1: Create a Forge Application

If you do not already have a Forge project, create one using the Forge CLI.

Bash
forge create

Choose an appropriate application template, such as a Jira issue panel.

Move into the generated project directory:

Bash
cd jira-ai-assistant

Install the Forge LLM package:

Bash
npm install @forge/llm

This package provides the SDK used to communicate with Atlassian-hosted language models.

It includes methods for listing available models, sending chat requests, and streaming responses.

Step 2: Configure the LLM Module

Open the manifest.yml file.

Add the LLM module configuration:

VB.NET
modules:
  llm:
    - key: jira-ai-llm
      model:
        - claude

  jira:issuePanel:
    - key: jira-ai-panel
      resource: main
      resolver:
        function: resolver
      title: AI Issue Assistant

  function:
    - key: resolver
      handler: index.handler

The important configuration is:

Code
llm:
  - key: jira-ai-llm
    model:
      - claude

The llm module enables access to the supported model family.

At present, the documented module configuration uses the Claude family.

There is an important deployment consideration. Adding the LLM module to an existing Forge application triggers a major version upgrade and requires administrators of existing installations to review and approve the update.

This is particularly important for Marketplace applications because adding an AI capability changes the app's functionality and data-processing behavior.

Step 3: Create a Basic LLM Request

Create or update the backend function file.

For this example, we will build a function that summarizes a Jira issue description.

JavaScript
import { chat } from "@forge/llm";

export async function summarizeIssue(issueDescription) {
    const response = await chat({
        model: "claude-sonnet-4-6",
        messages: [
            {
                role: "system",
                content:
                    "You are an assistant that summarizes Jira issues. " +
                    "Use clear and simple language."
            },
            {
                role: "user",
                content:
                    `Summarize the following Jira issue:\n\n${issueDescription}`
            }
        ],
        max_completion_tokens: 500
    });

    const summary =
        response.choices?.[0]?.message?.content;

    return {
        summary,
        usage: response.usage
    };
}

The example uses a model identifier; verify that it is active for your Forge environment before deployment.

Let's understand the important parts.

The chat() method sends a request to the selected model.

The model property identifies which supported model should process the request.

The messages array contains the conversation. The system message establishes the assistant's behavior, while the user message contains the Jira issue information.

The max_completion_tokens property limits the generated response length.

Finally, the function extracts the generated text and returns the token usage information.

In production, validate the issue description before sending it to the model. Also handle cases where the response does not contain usable text.

Step 4: Connect the Function to the Forge Resolver

The backend function needs to be exposed through a Forge resolver so that the frontend can request an issue summary.

For example:

JavaScript
import Resolver from "@forge/resolver";
import { summarizeIssue } from "./llm-service";

const resolver = new Resolver();

resolver.define("summarizeIssue", async ({ payload }) => {
    const description = payload.description;

    if (
        typeof description !== "string" ||
        description.trim().length === 0
    ) {
        throw new Error("A valid issue description is required.");
    }

    return await summarizeIssue(description);
});

export const handler = resolver.getDefinitions();

The resolver performs basic input validation before invoking the LLM service.

This separation is useful because it keeps the frontend communication logic independent of the model integration.

For an actual Jira issue panel, retrieve the issue information through the appropriate Forge context or Jira API rather than trusting arbitrary issue data supplied by the browser.

Step 5: Display the AI Response in the Frontend

The frontend can call the resolver and display the generated summary.

A simplified Custom UI example looks like this:

JavaScript
import { invoke } from "@forge/bridge";

async function generateSummary(description) {
    const result = await invoke("summarizeIssue", {
        description
    });

    document.getElementById("summary").textContent =
        result.summary;
}

The invoke() method communicates with the backend resolver.

The generated content is displayed using textContent, which treats the response as text instead of interpreting it as HTML.

This is important because model-generated content should not be inserted directly into the page as executable markup.

A complete application should also provide loading indicators, error messages, and a way for users to request another summary.

Using Streaming for Longer AI Responses

Some AI operations take longer than a simple issue summary.

For example, a Confluence assistant might generate a detailed technical explanation or summarize a long project discussion.

Instead of waiting for the entire response, developers can use the stream() method.

JavaScript
import { stream } from "@forge/llm";

export async function generateExplanation(prompt) {
    const response = await stream({
        model: "claude-sonnet-4-6",
        messages: [
            {
                role: "user",
                content: prompt
            }
        ],
        max_completion_tokens: 1000
    });

    let generatedText = "";

    try {
        for await (const chunk of response) {
            const content =
                chunk.choices?.[0]?.delta?.content;

            if (typeof content === "string") {
                generatedText += content;
            }
        }

        return generatedText;
    } finally {
        await response.close();
    }
}

This example illustrates incremental response collection. Check the SDK response types for the selected model and package version when implementing the streaming consumer.

Streaming can improve the perceived responsiveness of an application because users do not have to wait for the complete response before seeing generated content.

For long-running operations, consider using Forge asynchronous events and Forge Realtime to manage background execution and deliver updates to the frontend.

Using Function Calling to Build AI-Powered Workflows

The Forge LLMs API also supports tool definitions.

This allows a model to request that an application execute a specific function when additional information or an operation is required.

Consider a Jira assistant that can retrieve an issue's status.

You can define a tool that describes the available operation:

JavaScript
const tools = [
    {
        type: "function",
        function: {
            name: "get_issue_status",
            description:
                "Retrieve the current status of a Jira issue.",
            parameters: {
                type: "object",
                properties: {
                    issueKey: {
                        type: "string",
                        description: "Jira issue key"
                    }
                },
                required: ["issueKey"]
            }
        }
    }
];

Pass the tool definition to the model:

JavaScript
const response = await chat({
    model: "claude-sonnet-4-6",
    messages: [
        {
            role: "user",
            content:
                "Check the status of issue DEV-101."
        }
    ],
    tools,
    tool_choice: "auto"
});

The model may return a tool call instead of a normal text response.

The application must inspect the returned tool call, validate its arguments, execute the corresponding backend function, and send the result back to the model.

The model should never be allowed to execute arbitrary application code.

For production implementations, use an explicit allowlist of supported functions and validate every argument before execution.

This approach can support workflows such as:

  • Retrieving Jira issue information.
  • Summarizing project activity.
  • Finding related Confluence pages.
  • Preparing workflow recommendations.
  • Generating structured project reports.

Choosing the Right Model for Your Application

Not every AI feature needs the most powerful available model.

The appropriate choice depends on response quality, processing requirements, and operating cost.

Model familySuitable workloadsConsideration
Claude HaikuShort summaries and simple classificationLightweight tasks
Claude SonnetGeneral-purpose assistants and analysisBalanced capabilities
Claude OpusComplex reasoning and multi-step tasksHigher resource consumption

These are general selection guidelines. Check the current Forge model catalogue for exact model identifiers, availability, and capabilities.

The SDK also provides a list() method that allows an application to inspect supported models and their status.

This is useful when maintaining applications across multiple environments.

Security, Privacy, and Usage Considerations

Using a hosted LLM does not remove the responsibility to protect customer information.

Developers should consider the following areas.

Data access

Only retrieve the Jira or Confluence information required for the user's request.

Do not send entire project datasets when a small amount of relevant context is sufficient.

User permissions

The application should respect the permissions of the user requesting the AI operation.

A model should not gain access to restricted Jira issues simply because the backend application has broader API permissions.

Prompt injection

Issue descriptions and Confluence pages can contain instructions that attempt to manipulate the model.

Treat retrieved content as untrusted input and avoid allowing document text to override the system instructions.

Usage and billing

Forge LLM usage is billed to the developer of the application.

Usage is measured through input and output tokens, which are converted into credits according to the selected model.

The API response includes usage information that can help developers monitor consumption.

There is no free monthly usage allowance for the Forge LLMs API, so estimate costs before releasing an AI feature to a large customer base.

The documented per-installation limits also include 100 requests per minute and 500,000 tokens per minute. Check the current model-specific context limits and other service restrictions before deployment.

Common Mistakes When Integrating Forge LLMs

MistakeWhy it causes problemsRecommended approach
Forgetting the LLM manifest moduleThe SDK cannot be used correctlyConfigure the llm module
Using an inactive modelRequests can failCheck available model status
Sending unrestricted issue dataIncreases privacy risk and token consumptionRetrieve only relevant information
Ignoring token usageCreates unexpected costsMonitor input and output tokens
Trusting tool arguments directlyCan cause unauthorized operationsValidate every tool call
Ignoring streaming failuresProduces incomplete responsesHandle partial output and errors
Exposing LLM calls in the frontendRisks exposing application logicInvoke the model from backend functions

Best Practices for Production Forge Applications

  1. Keep model calls in backend functions rather than exposing them directly to the browser.
  2. Select models according to task complexity and cost requirements.
  3. Limit the amount of Jira and Confluence data included in prompts.
  4. Validate user input and retrieved content before sending it to the model.
  5. Use tool calling only for explicitly permitted application operations.
  6. Handle rate limits, timeouts, and incomplete responses.
  7. Track token usage for each important AI operation.
  8. Provide clear loading and error states in the user interface.
  9. Review the Marketplace installation and administrator approval requirements before introducing the LLM module.
  10. Test the application with realistic customer data and different permission levels.

Advantages and Disadvantages of the Forge LLMs API

Advantages

  • Uses Atlassian-hosted language models.
  • Reduces the need to manage external model infrastructure.
  • Avoids separate external AI provider credentials for supported requests.
  • Supports chat, streaming, and function calling.
  • Provides usage information for cost monitoring.
  • Can preserve eligibility for the Runs on Atlassian badge when other requirements are met.

Disadvantages

  • Developers have less freedom to choose providers outside the supported model catalogue.
  • Usage is billable and has no free monthly allowance.
  • Model availability and capabilities can change.
  • Applications must handle rate limits and token restrictions.
  • Existing installations require administrator approval when the LLM module is introduced.
  • Developers remain responsible for application-level security and access control.

Summary

The Atlassian Forge LLMs API provides a practical way to introduce AI capabilities into Jira and Confluence applications without independently managing model infrastructure.

Using the @forge/llm SDK, developers can send chat requests, stream generated responses, inspect token usage, and build workflows that use function calling.

The most important part of a successful implementation is not simply connecting a model. It is controlling which application data enters the prompt, validating generated responses, respecting user permissions, and monitoring usage costs.

For developers building applications within the Atlassian ecosystem, Forge LLMs provides a useful foundation for creating AI-assisted workflows while keeping supported model interactions within Atlassian-managed infrastructure.