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.
README
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(replaceyour-companywith your subdomain) and copy thecloudIdvalue - 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:
- Clone and build:
git clone https://github.com/expel-io/atlassian-goals-mcp.git
cd atlassian-goals-mcp
npm install
npm run build
- 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"
}
}
}
}
- Optionally create a
.envfile 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 20status(optional): one ofNOT_STARTED,IN_PROGRESS,COMPLETED,CANCELLEDsearchTerm(optional): partial-match filter on goal nametags(optional): array of tag names; multiple tags AND togethercursor(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_tracklimit(optional): 1–100, default 20cursor(optional): pagination cursor
Projects — Read
list_projects
List projects with optional name filtering and cursor pagination.
Parameters:
limit(optional): 1–100, default 20searchTerm(optional): partial-match filter on project namecursor(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 20cursor(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 = off_track, 40–60 = at_risk, 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 ARIsummary(required): the visible headline, max 280 charsdetails(optional): longer-form "More detail" body (no length limit)status(optional): see abovescore(optional): integer 1–100targetDate(optional):{ date: "YYYY-MM-DD", confidence?: "EXACT"|"QUARTER"|"HALF"|"YEAR" }metricUpdates(optional):[{ targetId, value }]—targetIdis the metric target ID fromget_goaldryRun(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 ARIgoalUpdateId(required): update ARI (ari:cloud:townsquare:{cloudId}:goal-update/{uuid})summary,details,status,score,targetDate(all optional): same aspost_goal_updatemetricUpdates(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 goaldryRun(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 ARIname(optional): new goal namedescription(optional): markdownownerId(optional): Atlassian account ID (the valueget_goalreturns asowner.accountId)targetDate(optional):{ date, confidence? }startDate(optional):YYYY-MM-DDarchived(optional): booleandryRun(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 ARItagNames(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 ARItagNames(optional): array of tag names — looked up against the goal's current tags; errors if a name is not currently attachedtagIds(optional): array of tag ARIs — provide eithertagNamesortagIdsdryRun(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 parsingutils/tql.test.ts— TQL escaping/injection preventionutils/goal-update-status.test.ts— score/status resolution for the update toolsatlassian/client.test.ts— rate limiting and error handlingatlassian/mutation-result.test.ts— write-mutation payload-error unwrappingtools/*.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:
- Set up your
.envfile with valid Atlassian credentials - Optionally set
TEST_OWNER_ACCOUNT_IDto a valid account ID from your workspace to test owner filtering. To find your account ID, look at theowner.accountIdfield on any goal returned byget_goal. - Run
npm run test:integration
Integration test suites:
connection.test.ts— API connectivity and configurationhealth-check.test.ts— health-check tool behaviorlist-goals.test.ts— goal listingget-goal.test.ts— single goal detailget-goals.test.ts— batch goal fetchingsearch-goals.test.ts— TQL goal searchprojects.test.ts— project list/get/searchupdates.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 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't expired
- Ensure your email matches the Atlassian account
- Check that your Cloud ID is correct
Connection Errors
If the server can't connect:
- Verify your site URL is correct
- Check your network connection
- Ensure you have access to the Atlassian Goals API
Configuration Errors
If you see "Invalid configuration" errors:
- Check all required environment variables are set
- Verify the format of your site URL (must be a valid URL)
- Ensure your email is in valid email format
Package Installation Errors
If npx fails to install or run the server, you may encounter authentication or network errors from your package manager:
Symptoms:
npm ERR! code E401ornpm ERR! 401 UnauthorizedETIMEDOUTorENOTFOUNDerrors- Proxy authentication failures
- Certificate verification errors
Common Causes:
- Corporate package registry proxies (Artifactory, Nexus, Verdaccio)
- npm registry authentication required
- Network proxy configuration
- SSL/TLS certificate issues
Debugging Steps:
-
Check npm registry configuration:
npm config get registry # Should show https://registry.npmjs.org/ for public packages -
Check for authentication requirements:
npm config get //registry.npmjs.org/:_authToken # If set, your npm may require authentication for public packages -
View all npm configuration:
npm config list # Look for proxy, registry, or cert settings -
Test registry access:
npm view @modelcontextprotocol/sdk version # Should return a version number if registry is accessible
Solutions:
- Corporate registry: Contact your IT team about accessing public npm packages
- Proxy settings: Configure npm proxy settings or use VPN
- Direct registry: Temporarily use the official npm registry:
npm config set registry https://registry.npmjs.org/ - Local installation: Clone the repository and use the local development setup instead of npx
Logging and Performance Monitoring
The server includes structured logging and performance profiling capabilities.
Environment Variables:
# Enable debug logging (logs INFO level and above)
DEBUG=true
# Enable trace logging (very verbose, includes timing details)
TRACE=true
# Show performance metrics in tool responses
SHOW_PERFORMANCE=true
Log Levels:
ERROR: Errors and failuresWARN: Warnings and potential issuesINFO: Tool calls, completions, and important eventsDEBUG: Detailed diagnostic information (requires DEBUG=true)TRACE: Very detailed tracing including timers (requires DEBUG=true and TRACE=true)
Log Format:
[2025-01-06T12:34:56.789Z] [INFO] Tool called: list_goals {"tool":"list_goals","operation":"start","args":"{\"limit\":20}"}
[2025-01-06T12:34:57.123Z] [INFO] Tool completed: list_goals (334ms) {"tool":"list_goals","operation":"complete","duration":334,"resultSize":1250}
Performance Profiling:
- Automatic timing for all tool calls
- Duration logged in milliseconds
- Result size tracking
- Optional performance metrics in responses (with SHOW_PERFORMANCE=true)
Viewing Logs:
- Logs are written to stderr (stdout is reserved for MCP JSON-RPC)
- In Claude Desktop: View logs in developer console
- In terminal: Redirect stderr to file:
node build/index.js 2> logs.txt
Debug Mode
Enable debug logging by adding to your environment variables:
DEBUG=true
API Reference
This server uses the Atlassian Goals GraphQL API. For more information:
License
MIT License - see LICENSE file for details
Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
Support
For issues related to:
- This MCP server: Open an issue in this repository
- Atlassian Goals API: Visit Atlassian Developer Community
- Claude Desktop: Visit Anthropic Support
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。