# Forge Rovo Agent

> Add an Atlassian Rovo AI agent to a Forge app with manifest configuration, action definitions, and backend handlers. Use when integrating Rovo agents, creating Forge agent actions, building CQL-based tools, or adding AI assistant capabilities to Confluence Forge apps.

- Skill: `raghav1257/forge-rovo-agent` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add raghav1257/forge-rovo-agent`
- Raw SKILL.md: https://api.skillmd.com/api/skills/raghav1257/forge-rovo-agent/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: raghav1257 (https://skillmd.com/u/raghav1257)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/raghav1257/forge-rovo-agent

---


# Forge Rovo Agent Integration

Adds a Rovo AI agent to an Atlassian Forge app. The agent is declared in
`manifest.yml` and backed by Forge function handlers that call Confluence APIs.

## Architecture Overview

```
User (Rovo chat) → Rovo runtime → manifest.yml (agent + actions) → Forge functions (src/index.ts) → Confluence REST APIs
```

- **Declarative layer**: `rovo:agent` + `action` modules in `manifest.yml`
- **Implementation layer**: exported async functions using `@forge/api`
- **No agent-specific frontend code** -- Rovo handles the chat UI

## When to Use

- Adding an AI agent to an existing Forge app
- Creating Rovo actions that query or mutate Confluence content
- Building CQL-based reporting/search agents
- Generating Confluence pages with embedded macros via Rovo
- Creating pages containing any of the app's Forge macros (generic pattern)

## Step-by-Step Integration

### 1. Add dependencies

```bash
# @forge/api is required for backend Confluence calls
yarn add @forge/api@^4
# Upgrade @forge/bridge if needed for emitsReadyEvent support
yarn add @forge/bridge@^5
```

### 2. Configure manifest.yml

Add three module types under `modules:`:

```yaml
modules:
  rovo:agent:
    - key: your-agent-key
      name: Your Agent Name
      description: What the agent does (shown to users)
      prompt: |
        System prompt instructing the agent's behavior.
        Include: what to extract from user input, which actions to call,
        how to format responses, and fallback behavior.
      conversationStarters:
        - "Example prompt 1"
        - "Example prompt 2"
      actions:
        - your-action-key

  action:
    - key: your-action-key
      function: yourFunction      # Must match function key below
      actionVerb: GET             # GET | CREATE | UPDATE | DELETE
      description: What this action does (used by Rovo to decide when to call it)
      inputs:
        paramName:
          title: Human-readable label
          type: string            # string | integer | boolean
          required: true
          description: "Description with examples"

  function:
    - key: yourFunction
      handler: index.yourFunction  # file.exportedFunctionName
```

### 3. Add required scopes

```yaml
permissions:
  scopes:
    - read:chat:rovo              # Always required for Rovo agents
    # Add API-specific scopes:
    - search:confluence           # For CQL search
    - read:page:confluence        # For reading pages
    - write:page:confluence       # For creating/updating pages
    - read:space:confluence       # For space lookups
```

### 4. Implement function handlers

Create `src/index.ts` with exported async functions matching your `function` keys:

```typescript
import api, { route } from '@forge/api';

export async function yourFunction(payload: YourPayload) {
  // Validate inputs
  if (!payload.requiredField) {
    return { error: 'requiredField is required.' };
  }

  // Call Confluence API
  const response = await api.asUser().requestConfluence(
    route`/wiki/rest/api/your-endpoint?param=${payload.requiredField}`,
    { method: 'GET' }
  );

  const data = await response.json();

  // Return structured data (Rovo renders this for the user)
  return { results: data.results, count: data.results.length };
}
```

### 5. Frontend: emit ready event (if app has macros)

If your app has Custom UI macros, add `emitsReadyEvent: true` to the macro
module and call `view.emitReadyEvent()` after the macro loads. This is required
for Rovo-embedded macro previews.

## Key Patterns

### Context placeholder substitution
Replace `currentSpace()` / `currentPage()` in CQL with actual values from
`payload.context.confluence`:

```typescript
function substituteContextPlaceholders(cql: string, context?: any): string {
  let result = cql;
  if (context?.confluence?.spaceKey) {
    result = result.replace(/currentSpace\(\)/g, `"${context.confluence.spaceKey}"`);
  }
  if (context?.confluence?.contentId) {
    result = result.replace(/currentPage\(\)/g, context.confluence.contentId);
  }
  return result;
}
```

### Structured error responses
Always return `{ error: string }` objects instead of throwing -- Rovo displays
these to the user gracefully.

### Space ID resolution
Accept both numeric IDs and space keys, resolve keys via
`GET /wiki/api/v2/spaces?keys=KEY`.

### ADF macro embedding (generic — works for any Forge macro)
Build Atlas Document Format with `extension` nodes to embed **any** of the
app's macros in created pages. The pattern accepts a dynamic `macroKey`
(matching the macro's key in `manifest.yml`) and a generic `macroParams`
map (matching the macro's config schema). This works whether the app has
1 macro or 100 — the Rovo action just passes the right key and params.

See [handler-reference.md](handler-reference.md) for the full
`buildAdfWithForgeMacro` pattern and the generic page creation handler.

## Prompt Writing Tips

- Be explicit about which actions to call and when
- Include CQL examples in the prompt so the agent can construct queries
- Tell the agent how to format results (table columns, ordering)
- Include fallback behavior (no results, errors, refinement)
- Add a follow-up suggestion pattern (e.g., "offer to save as a page")

## Checklist

- [ ] `@forge/api` added to dependencies
- [ ] `rovo:agent` module defined with prompt + conversation starters
- [ ] `action` modules defined with typed inputs
- [ ] `function` modules mapped to handler exports
- [ ] `read:chat:rovo` scope added
- [ ] API-specific scopes added (`write:page:confluence` if creating pages)
- [ ] Backend handlers validate inputs and return structured data
- [ ] Error responses use `{ error: string }` pattern
- [ ] Macros have `emitsReadyEvent: true` if applicable
- [ ] If page-creation action: uses generic `buildAdfWithForgeMacro` with dynamic macro key + params
- [ ] If page-creation action: app ID in `manifest.yml` matches the `extensionType` ARI used in ADF

## Additional Resources

- Full manifest patterns: [manifest-reference.md](manifest-reference.md)
- Backend handler code: [handler-reference.md](handler-reference.md)

