AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Atlassian Goals Mcp

mcp-expel-io-atlassian-goals-mcp · by expel-io

Workaround since Atlassian's Rovo MCP server doesn't (yet) support their goals product.

No reviews yet
0 installs
29 views
0.0% view→install

Install

$ agentstack add mcp-expel-io-atlassian-goals-mcp

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-expel-io-atlassian-goals-mcp)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
4mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Atlassian Goals Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Atlassian Goals MCP Server

A Model Context Protocol (MCP) server for the Atlassian Goals API. Enables AI assistants like Claude to query, search, and update Atlassian Goals and Projects.

Features

Goals — Read

  • List, get (single or batch), and search goals via TQL (Townsquare Query Language)

Projects — Read

  • List, get (single or batch), and search projects via TQL

Goals — Write

  • Post weekly status updates (with summary, More detail, status/score, target date, and metric values)
  • Edit or delete the most recent update
  • Update goal metadata (name, description, owner, target/start date, archive flag)
  • Add or remove goal tags by name

Operational

  • Health check for API connectivity and authentication
  • Security: TQL injection prevention, input validation, request timeouts, retry with exponential backoff
  • Performance: rate limiting, automatic throttling, structured logging
  • Robustness: enhanced ADF parser supporting 15+ node types; markdown→ADF conversion for write fields

Prerequisites

  • Node.js >= 18.0.0 (comes with Claude Desktop)
  • Atlassian Cloud account with Goals access
  • Atlassian API token

Quick Start

1. Get Your Atlassian Credentials

You'll need these four values:

  • Email: Your Atlassian account email
  • API Token: Generate at https://id.atlassian.com/manage-profile/security/api-tokens
  • Cloud ID: Visit https://your-company.atlassian.net/_edge/tenant_info (replace your-company with your subdomain) and copy the cloudId value
  • Site URL: Your Atlassian site URL (e.g., https://your-company.atlassian.net)

2. Add to Claude Desktop

Open your Claude Desktop config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Add this configuration (replace the placeholder values with your credentials from step 1):

{
  "mcpServers": {
    "atlassian-goals": {
      "command": "npx",
      "args": ["-y", "github:expel-io/atlassian-goals-mcp"],
      "env": {
        "ATLASSIAN_EMAIL": "your-email@example.com",
        "ATLASSIAN_API_TOKEN": "your-api-token",
        "ATLASSIAN_CLOUD_ID": "your-cloud-id",
        "ATLASSIAN_SITE_URL": "https://your-subdomain.atlassian.net"
      }
    }
  }
}

3. Restart Claude Desktop

Restart Claude Desktop to load the MCP server.

That's it! You can now ask Claude about your Atlassian Goals.

Local Development

If you want to modify or contribute to this server:

  1. Clone and build:
git clone https://github.com/expel-io/atlassian-goals-mcp.git
cd atlassian-goals-mcp
npm install
npm run build
  1. Update your Claude Desktop config to use the local build:
{
  "mcpServers": {
    "atlassian-goals": {
      "command": "node",
      "args": ["/absolute/path/to/atlassian-goals-mcp/build/index.js"],
      "env": {
        "ATLASSIAN_EMAIL": "your-email@example.com",
        "ATLASSIAN_API_TOKEN": "your-api-token",
        "ATLASSIAN_CLOUD_ID": "your-cloud-id",
        "ATLASSIAN_SITE_URL": "https://your-subdomain.atlassian.net"
      }
    }
  }
}
  1. Optionally create a .env file for testing:
cp .env.example .env
# Edit .env with your credentials

Available Tools

Tools are grouped by surface area. All goal/update IDs are Atlassian ARIs (e.g. ari:cloud:townsquare:{cloudId}:goal/{uuid}); the formats are validated by each tool's input schema.

Goals — Read

list_goals

List goals with optional filtering by status, name, or tags. Supports cursor-based pagination.

Parameters:

  • limit (optional): 1–100, default 20
  • status (optional): one of NOT_STARTED, IN_PROGRESS, COMPLETED, CANCELLED
  • searchTerm (optional): partial-match filter on goal name
  • tags (optional): array of tag names; multiple tags AND together
  • cursor (optional): pagination cursor from a previous response
get_goal

Fetch a single goal with description, owner, metrics, parent/sub-goal relationships, tags, and recent updates.

Parameters:

  • goalId (required): goal ARI
get_goals

Batch-fetch multiple goals in one request. More efficient than calling get_goal repeatedly.

Parameters:

  • goalIds (required): array of goal ARIs (1–20)
search_goals

Search goals using TQL (Townsquare Query Language).

Operators: LIKE (partial, supports _ as a single-character wildcard), = (exact), AND, OR. Fields: name, status (pending / on_track / at_risk / off_track / done / cancelled), owner (account ID), tag.

Parameters:

  • searchString (required): a TQL query, e.g. name LIKE "Q4" AND status = on_track
  • limit (optional): 1–100, default 20
  • cursor (optional): pagination cursor

Projects — Read

list_projects

List projects with optional name filtering and cursor pagination.

Parameters:

  • limit (optional): 1–100, default 20
  • searchTerm (optional): partial-match filter on project name
  • cursor (optional): pagination cursor
get_project

Fetch a single project with description, owner, members, linked goals, and recent updates.

Parameters:

  • projectId (required): project ARI (ari:cloud:townsquare:{cloudId}:project/{uuid})
get_projects

Batch-fetch multiple projects (1–20 per call).

Parameters:

  • projectIds (required): array of project ARIs
search_projects

Search projects using TQL. Currently supports LIKE on name with OR.

Parameters:

  • searchString (required): TQL query, e.g. name LIKE "Integration"
  • limit (optional): 1–100, default 20
  • cursor (optional): pagination cursor

Goals — Write

post_goal_update

Post a weekly status update — the entry that appears in the goal's Updates tab.

Status/score model: on_track/at_risk/off_track are derived from a 1–100 integer score (the Atlassian UI labels these as decimals like "0.8", but the API stores integers). Bands: 10–30 = offtrack, 40–60 = atrisk, 70–100 = on_track. Status alone fills the band midpoint; score alone infers status; combined values are validated. pending/paused/done/cancelled/archived take only status — no score.

Markdown is supported in both summary and details and is converted to ADF before send.

Parameters:

  • goalId (required): goal ARI
  • summary (required): the visible headline, max 280 chars
  • details (optional): longer-form "More detail" body (no length limit)
  • status (optional): see above
  • score (optional): integer 1–100
  • targetDate (optional): { date: "YYYY-MM-DD", confidence?: "EXACT"|"QUARTER"|"HALF"|"YEAR" }
  • metricUpdates (optional): [{ targetId, value }]targetId is the metric target ID from get_goal
  • dryRun (optional): return the resolved mutation payload without submitting
edit_goal_update

Edit a previously-posted update. Partial fields are supported; at least one editable field is required.

Both goalId and goalUpdateId are required so the tool can pre-query existing update notes and pass updateNoteId when replacing details — without it, Townsquare appends a second note that the UI doesn't render.

Note the metric-input asymmetry with post_goal_update: metricUpdates takes metricId (the metric itself), not targetId (the metric target).

Parameters:

  • goalId (required): goal ARI
  • goalUpdateId (required): update ARI (ari:cloud:townsquare:{cloudId}:goal-update/{uuid})
  • summary, details, status, score, targetDate (all optional): same as post_goal_update
  • metricUpdates (optional): [{ metricId, value }]
  • dryRun (optional)
delete_latest_goal_update

Remove the most recent update on a goal. The Townsquare API only deletes the latest update per goal; earlier updates cannot be removed this way.

Parameters:

  • goalUpdateId (required): update ARI; must be the latest on its goal
  • dryRun (optional)
update_goal

Edit a goal's metadata. Status changes are NOT done here — use post_goal_update. Tags are also separate — use add_goal_tags / remove_goal_tags.

description accepts markdown and is converted to ADF. archived: true archives the goal (destructive in effect — confirm with the user before flipping on a real goal).

Parameters:

  • goalId (required): goal ARI
  • name (optional): new goal name
  • description (optional): markdown
  • ownerId (optional): Atlassian account ID (the value get_goal returns as owner.accountId)
  • targetDate (optional): { date, confidence? }
  • startDate (optional): YYYY-MM-DD
  • archived (optional): boolean
  • dryRun (optional)

At least one editable field is required.

add_goal_tags

Attach tags to a goal by name. Tag names that don't yet exist at the workspace level are auto-created — the Townsquare API does not expose a delete-tag mutation, so prefer reusing existing names over inventing new ones.

Parameters:

  • goalId (required): goal ARI
  • tagNames (required): array of tag names (≥1)
  • dryRun (optional)
remove_goal_tags

Detach tags from a goal. Prefer tagNames — the tool looks up matching tag IDs from the goal's current tag list. tagIds is supported for callers that already have them.

Parameters:

  • goalId (required): goal ARI
  • tagNames (optional): array of tag names — looked up against the goal's current tags; errors if a name is not currently attached
  • tagIds (optional): array of tag ARIs — provide either tagNames or tagIds
  • dryRun (optional)

Operational

health_check

Verify API connectivity, authentication, and performance.

Parameters:

  • verbose (optional): include diagnostic details (default false)

Development

Build

npm run build

Watch Mode

For development with automatic rebuilding:

npm run watch

Project Structure

atlassian-goals-mcp/
├── src/
│   ├── index.ts                          # Entry point
│   ├── server.ts                         # MCP server setup
│   ├── config.ts                         # Configuration management
│   ├── atlassian/
│   │   ├── client.ts                     # GraphQL client
│   │   ├── queries.ts                    # GraphQL query + mutation definitions
│   │   ├── mutation-result.ts            # Shared payload-error unwrap for write mutations
│   │   └── types.ts                      # TypeScript interfaces
│   ├── tools/
│   │   ├── index.ts                      # Tool registry + executeTool dispatch
│   │   ├── list-goals.ts                 # Goal tools — read
│   │   ├── get-goal.ts
│   │   ├── get-goals.ts
│   │   ├── search-goals.ts
│   │   ├── list-projects.ts              # Project tools — read
│   │   ├── get-project.ts
│   │   ├── get-projects.ts
│   │   ├── search-projects.ts
│   │   ├── post-goal-update.ts           # Goal tools — write
│   │   ├── edit-goal-update.ts
│   │   ├── delete-latest-goal-update.ts
│   │   ├── update-goal.ts
│   │   ├── add-goal-tags.ts
│   │   ├── remove-goal-tags.ts
│   │   └── health-check.ts
│   └── utils/
│       ├── logger.ts                     # Logging utility
│       ├── errors.ts                     # Error handling
│       ├── adf-parser.ts                 # ADF → text
│       ├── markdown-to-adf.ts            # Markdown → ADF JSON (write fields)
│       ├── goal-update-status.ts         # Score/status resolution shared by post/edit
│       ├── tql.ts                        # TQL escaping/builders
│       ├── goal-formatter.ts             # Read-tool formatting
│       └── project-formatter.ts          # Read-tool formatting
├── tests/
│   ├── unit/                             # Unit tests
│   ├── integration/                      # Integration tests
│   └── helpers/                          # Test utilities
├── scripts/                              # Introspection + live verification scripts
├── build/                                # Compiled output
├── package.json
├── tsconfig.json
├── vitest.config.ts                      # Test configuration
└── README.md

Testing

This project uses Vitest for testing with separate unit and integration test suites.

Running Tests

# Run all tests
npm test

# Run unit tests only (fast, no credentials needed)
npm run test:unit

# Run integration tests (requires .env configuration)
npm run test:integration

# Watch mode for development
npm run test:watch

# Generate coverage report
npm run test:coverage

# Interactive UI
npm run test:ui

Unit Tests

Unit tests are located in tests/unit/ and test individual functions and modules in isolation. They don't require API credentials and should run quickly.

Coverage:

  • utils/adf-parser.test.ts — Atlassian Document Format parsing
  • utils/tql.test.ts — TQL escaping/injection prevention
  • utils/goal-update-status.test.ts — score/status resolution for the update tools
  • atlassian/client.test.ts — rate limiting and error handling
  • atlassian/mutation-result.test.ts — write-mutation payload-error unwrapping
  • tools/*.test.ts — schema validation for each tool

Integration Tests

Integration tests are located in tests/integration/ and test against the real Atlassian Goals API. They require valid credentials in your .env file.

Note: Integration tests are automatically skipped if credentials are not available. This allows unit tests to run in CI environments without requiring API access.

To run integration tests locally:

  1. Set up your .env file with valid Atlassian credentials
  2. Optionally set TEST_OWNER_ACCOUNT_ID to a valid account ID from your workspace to test owner filtering. To find your account ID, look at the owner.accountId field on any goal returned by get_goal.
  3. Run npm run test:integration

Integration test suites:

  • connection.test.ts — API connectivity and configuration
  • health-check.test.ts — health-check tool behavior
  • list-goals.test.ts — goal listing
  • get-goal.test.ts — single goal detail
  • get-goals.test.ts — batch goal fetching
  • search-goals.test.ts — TQL goal search
  • projects.test.ts — project list/get/search
  • updates.test.ts — goal update data structures

Write tools (post_goal_update, edit_goal_update, delete_latest_goal_update, update_goal, add_goal_tags, remove_goal_tags) are exercised by the scripts/test-*.js live-verification scripts rather than the integration test suite — they need a known-safe test goal to write against. See [Development Scripts](#development-scripts) below.

Development Scripts

# GraphQL schema introspection (npm-aliased)
npm run introspect:goal      # Inspect TownsquareGoal type
npm run introspect:types     # Inspect available types
npm run introspect:updates   # Inspect update types
npm run introspect:metric    # Inspect metric types

# Diagnostic tools
npm run diagnose:ari         # Test ARI format variations

Several more one-off scripts live in scripts/ and are run directly with node:

# Type introspection (used when adding write tools)
node scripts/introspect-write-inputs.js
node scripts/introspect-edit-delete.js
node scripts/introspect-tag-mutations.js
node scripts/introspect-mutations.js

# Live-verification harnesses for the write tools — each one posts/edits/
# deletes test data on a "Jeffrey Test" goal and reverts when possible.
# These are NOT in the integration test suite because they need a known-safe
# test goal to write against.
node scripts/test-post-goal-update.js
node scripts/test-edit-delete-goal-update.js
node scripts/test-update-goal.js
node scripts/test-tag-tools.js
node scripts/verify-update-notes-behavior.js

These scripts are useful for:

  • Exploring available GraphQL fields
  • Verifying write-tool behavior end-to-end against the live API
  • Troubleshooting API connectivity
  • Understanding the data schema

Troubleshooting

Authentication Errors

If you see authentication errors:

  • Verify your API token is correct and hasn

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.