Commit f098b50a authored by Mr.Dat's avatar Mr.Dat

Initial commit

parents
# Atlassian Configuration
SITE_NAME=your-site.atlassian.net
USER_EMAIL=your-email@example.com
API_TOKEN=your-api-token
# MCP Configuration
MCP_SERVER_NAME=mcp-atlassian-integration
MCP_SERVER_VERSION=1.0.0
# Logging Configuration
LOG_LEVEL=info
phuc-nt-mcp-jira-server-2.0.0.tgz
phuc-nt-mcp-jira-server-*.tgz
# Node modules
node_modules/
# Build files
dist/
# Coverage reports
coverage/
# Environment variables
.env
.env.local
.env.development
.env.test
.env.production
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea/
.vscode/
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# Temporary files
.tmp/
.temp/
mcp-jira-server-bundle*.zip
\ No newline at end of file
# Development directories
node_modules/
src/
tests/
dev_mcp-atlassian-test-client/
# Configuration files
.env
.env.example
.gitignore
tsconfig.json
jest.config.js
# Docker files
Dockerfile
docker-compose.yml
start-docker.sh
# Development files
*.log
*.tsbuildinfo
.vscode/
.idea/
# Test files
coverage/
*.test.ts
*.spec.ts
# Documentation (keep only essential docs)
docs/dev-guide/
docs/test-reports/
docs/plan/
# Other files
.git/
.github/
# CHANGELOG
## [2.1.1] - 2025-05-17
### 📝 Patch Release
- Documentation and metadata updates only. No code changes.
## [2.1.0] - 2025-05-17
### ✨ Refactor & Standardization
- Refactored the entire codebase to standardize resource/tool structure
- Completely removed the content-metadata resource, merged metadata into the page resource
- Updated and standardized developer documentation for easier extension and maintenance
- Ensured compatibility with the latest MCP SDK, improved security, scalability, and maintainability
- Updated `docs/introduction/resources-and-tools.md` to remove all references to content-metadata
### 🔧 Bug Fixes
- Fixed duplicate resource registration issues
- Improved resource management and registration process
- Resolved issues with conflicting resource patterns
## [2.0.0] - 2025-05-11
### ✨ Improvements
- Updated all APIs to latest versions (Jira API v3, Confluence API v2)
- Improved documentation and README structure
- Reorganized resources and tools into logical groups
### 🎉 New Features
- **Jira Board & Sprint:** Management of boards, sprints, and issues for Agile/Scrum workflows
- **Jira Dashboard & Gadgets:** Create/update dashboards, add/remove gadgets
- **Jira Filters:** Create, view, update, delete search filters for issues
- **Advanced Confluence Pages:** Version management, attachments, page deletion
- **Confluence Comments:** Update and delete comments
- Expanded from 21 to 48 features, including numerous new tools for both Jira and Confluence
### 🔧 Bug Fixes
- Fixed issues with Jira dashboard and gadget tools/resources
- Resolved problems with jira://users resource
- Improved error handling and messaging
- Fixed compatibility issues between API versions
### 🔄 Code Changes
- Restructured codebase for easier future expansion
- Improved feature implementation workflow
\ No newline at end of file
# Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile
FROM node:18-slim
WORKDIR /app
# Sao chép các file cấu hình
COPY package*.json ./
COPY tsconfig.json ./
# Cài đặt các phụ thuộc
RUN npm ci
# Sao chép mã nguồn
COPY src ./src
# Build TypeScript thành JavaScript
RUN npm run build
# Mở port mặc định cho SSE transport (sẽ cập nhật sau)
EXPOSE 8080
# Biến môi trường mặc định
ENV NODE_ENV=production
# Khởi động MCP Server sử dụng STDIO transport
# Lưu ý: Sẽ cập nhật để hỗ trợ SSE transport sau
CMD ["node", "dist/index.js"]
MIT License
Copyright (c) 2024 phuc-nt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
\ No newline at end of file
# MCP Atlassian Server (by phuc-nt)
<p align="center">
<img src="assets/logo_icon.png" alt="Atlassian Logo" width="120" />
</p>
[![MCP Atlassian Server (by phuc-nt)](https://img.shields.io/badge/MCP%20Marketplace--Pending%20Review-orange)](https://github.com/phuc-nt/mcp-jira-server)
[![smithery badge](https://smithery.ai/badge/mcp-jira-server)](https://smithery.ai/server/mcp-jira-server)
## What's New in Version 2.1.1 🚀
- Refactored the entire codebase to standardize resource/tool structure, completely removed the content-metadata resource, and merged metadata into the page resource.
- New developer guide: anyone can now easily extend and maintain the codebase.
- Ensured compatibility with the latest MCP SDK, improved security, scalability, and maintainability.
- Updated `docs/introduction/resources-and-tools.md` to remove all references to content-metadata.
👉 **See the full [CHANGELOG](./CHANGELOG.md) for details.**
## What's New in Version 2.0.1 🎉
**MCP Atlassian Server v2.0.1** brings a major expansion of features and capabilities!
- **Updated APIs**: Now using the latest Atlassian APIs (Jira API v3, Confluence API v2)
- **Expanded Features**: Grown from 21 to 48 features, including advanced Jira and Confluence capabilities
- **Enhanced Board & Sprint Management**: Complete Agile/Scrum workflow support
- **Advanced Confluence Features**: Page version management, attachments handling, and comment management
- **Improved Resource Registration**: Fixed duplicate resource registration issues for a more stable experience
- **Documentation Update**: New comprehensive documentation series explaining MCP architecture, resource/tool development
For full details on all changes, improvements, and fixes, see the [CHANGELOG](./CHANGELOG.md).
## Introduction
**MCP Atlassian Server (by phuc-nt)** is a Model Context Protocol (MCP) server that connects AI agents like Cline, Claude Desktop, or Cursor to Atlassian Jira and Confluence, enabling them to query data and perform actions through a standardized interface.
> **Note:** This server is primarily designed and optimized for use with Cline, though it follows the MCP standard and can work with other MCP-compatible clients.
![Introduction Demo](https://raw.githubusercontent.com/phuc-nt/public-assets/main/mcp-jira-server/introduce.gif)
- **Key Features:**
- Connect AI agents to Atlassian Jira and Confluence
- Support both Resources (read-only) and Tools (actions/mutations)
- Easy integration with Cline through MCP Marketplace
- Local-first design for personal development environments
- Optimized integration with Cline AI assistant
## The Why Behind This Project
As a developer working daily with Jira and Confluence, I found myself spending significant time navigating these tools. While they're powerful, I longed for a simpler way to interact with them without constantly context-switching during deep work.
The emergence of AI Agents and the Model Context Protocol (MCP) presented the perfect opportunity. I immediately saw the potential to connect Jira and Confluence (with plans for Slack, GitHub, Calendar, and more) to my AI workflows.
This project began as a learning journey into MCP and AI Agents, but I hope it evolves into something truly useful for individuals and organizations who interact with Atlassian tools daily.
## System Architecture
```mermaid
graph TD
AI[Cline AI Assistant] <--> MCP[MCP Atlassian Server]
MCP <--> JiraAPI[Jira API]
MCP <--> ConfAPI[Confluence API]
subgraph "MCP Server"
Resources[Resources - Read Only]
Tools[Tools - Actions]
end
Resources --> JiraRes[Jira Resources<br/>issues, projects, users]
Resources --> ConfRes[Confluence Resources<br/>spaces, pages]
Tools --> JiraTools[Jira Tools<br/>create, update, transition]
Tools --> ConfTools[Confluence Tools<br/>create page, comment]
```
## Installation & Setup
For detailed installation and setup instructions, please refer to our [installation guide for AI assistants](./llms-install.md). This guide is specially formatted for AI/LLM assistants like Cline to read and automatically set up the MCP Atlassian Server.
> **Note for Cline users**: The installation guide (llms-install.md) is optimized for Cline AI to understand and execute. You can simply ask Cline to "Install MCP Atlassian Server (by phuc-nt)" and it will be able to parse the instructions and help you set up everything step-by-step.
The guide includes:
- Prerequisites and system requirements
- Step-by-step setup for Node.js environments
- Configuring Cline AI assistant to connect with Atlassian
- Getting and setting up Atlassian API tokens
- Security recommendations and best practices
### Installing via Smithery
To install Atlassian Integration Server for Claude Desktop automatically via [Smithery](https://smithery.ai/server/mcp-jira-server):
```bash
npx -y @smithery/cli install mcp-jira-server --client claude
```
## Feature Overview
MCP Atlassian Server enables AI assistants (like Cline, Claude Desktop, Cursor...) to access and manage Jira & Confluence with a full set of features, grouped for clarity:
### Jira
- **Issue Management**
- View, search, and filter issues
- Create, update, transition, and assign issues
- Add issues to backlog or sprint, rank issues
- **Project Management**
- View project list, project details, and project roles
- **Board & Sprint Management**
- View boards, board configuration, issues and sprints on boards
- Create, start, and close sprints
- **Filter Management**
- View, create, update, and delete filters
- **Dashboard & Gadget Management**
- View dashboards and gadgets
- Create and update dashboards
- Add or remove gadgets on dashboards
- **User Management**
- View user details, assignable users, and users by project role
### Confluence
- **Space Management**
- View space list, space details, and pages in a space
- **Page Management**
- View, search, and get details of pages, child pages, ancestors, attachments, and version history
- Create, update, rename, and delete pages
- **Comment Management**
- View, add, update, and delete comments on pages
> For a full technical breakdown of all features, resources, and tools, see:
> [docs/introduction/resources-and-tools.md](./docs/introduction/resources-and-tools.md)
---
## Request Flow
```mermaid
sequenceDiagram
participant User
participant Cline as Cline AI
participant MCP as MCP Server
participant Atlassian as Atlassian API
User->>Cline: "Find all my assigned issues"
Cline->>MCP: Request jira://issues
MCP->>Atlassian: API Request with Auth
Atlassian->>MCP: JSON Response
MCP->>Cline: Formatted MCP Resource
Cline->>User: "I found these issues..."
User->>Cline: "Create new issue about login bug"
Cline->>MCP: Call createIssue Tool
MCP->>Atlassian: POST /rest/api/3/issue
Atlassian->>MCP: Created Issue Data
MCP->>Cline: Success Response
Cline->>User: "Created issue DEMO-123"
```
## Security Note
- Your API token inherits all permissions of the user that created it
- Never share your token with a non-trusted party
- Be cautious when asking LLMs to analyze config files containing your token
- See detailed security guidelines in [llms-install.md](./llms-install.md#security-warning-when-using-llms)
## Contribute & Support
- Contribute by opening Pull Requests or Issues on GitHub.
- Join the MCP/Cline community for additional support.
\ No newline at end of file
# MCP Atlassian Server 2.1.1
🚀 **Major refactor: Standardized resource/tool structure, removed content-metadata resource, updated developer documentation!**
Available on npm (mcp-jira-server) or download directly. Use with Cline or any MCP-compatible client.
---
### Updates in 2.1.1
**Refactor & Standardization**
- Refactored the entire codebase to standardize resource/tool structure, completely removed the content-metadata resource, and merged metadata into the page resource.
- Updated and standardized developer documentation, making it easy for any developer to extend and maintain.
- Ensured compatibility with the latest MCP SDK, improved security, scalability, and maintainability.
- Updated `docs/introduction/resources-and-tools.md` to remove all references to content-metadata.
**Bug Fixes**
- Fixed duplicate resource registration issues for a more stable experience
- Improved resource management and registration process
- Resolved issues with conflicting resource patterns
**Documentation Series**
- Added comprehensive documentation series:
1. MCP Overview & Architecture: Core concepts and design principles
2. MCP Tools & Resources Development: How to develop and extend resources/tools
3. MCP Prompts & Sampling: Guide for prompt engineering with MCP
- Updated installation guide and client development documentation
- Enhanced resource and tool descriptions
**Core Features**
**Jira Information Access**
- View issues, projects, users, comments, transitions, assignable users
- Access boards, sprints, filters, dashboards and gadgets
- Search issues with powerful filter tools
**Jira Actions**
- Create, update, transition, assign issues
- Manage boards and sprints for Agile/Scrum workflows
- Create/update dashboards, add/remove gadgets
- Create, update, and delete filters
**Confluence Information Access**
- View spaces, pages, child pages, details, comments, labels
- Access page versions and attachments
- View and search comments
**Confluence Actions**
- Create and update pages, add/remove labels, add comments
- Manage page versions, upload/download attachments
- Update and delete comments
- Delete pages
---
**How to use:**
1. Install from npm: `npm install -g mcp-jira-server`
2. Point Cline config to the installed package.
3. Set your Atlassian API credentials.
4. Start using natural language to work with Jira & Confluence!
See [README.md](https://github.com/phuc-nt/mcp-jira-server) and the new documentation series for full instructions.
Feedback and contributions are welcome! 🚀
## What's Changed
* Fixed resource registration to prevent duplicates
* Improved server stability and resource management
* Added comprehensive documentation series in `docs/knowledge/`
* Enhanced development guide for client integrations
* Updated resource structure for better organization
**Previous Changelog (2.0.0)**:
* Updated to latest Atlassian APIs (Jira API v3, Confluence API v2)
* Redesigned resource and tool structure for better organization
* Expanded Jira capabilities with board, sprint, dashboard, and filter management
* Enhanced Confluence features with advanced page operations and comment management
**Full Changelog**: https://github.com/phuc-nt/mcp-jira-server/blob/main/CHANGELOG.md
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
{
"name": "dev_mcp-atlassian-test-client",
"version": "1.0.0",
"description": "Test client for MCP Atlassian server",
"type": "module",
"main": "dist/tool-test.js",
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"dev": "ts-node --esm src/index.ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.11.0"
},
"devDependencies": {
"@types/node": "^22.15.2",
"ts-node": "^10.9.2",
"typescript": "^5.8.3"
}
}
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import path from "path";
import { fileURLToPath } from "url";
// Get current file path
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
async function main() {
const client = new Client({ name: "mcp-atlassian-inventory-list", version: "1.0.0" });
const serverPath = "/Users/phucnt/Workspace/mcp-jira-server/dist/index.js";
const transport = new StdioClientTransport({
command: "node",
args: [serverPath],
env: process.env as Record<string, string>
});
console.log("Connecting to MCP server...");
await client.connect(transport);
// List available tools with details
console.log("\n=== Available Tools ===");
const toolsResult = await client.listTools();
console.log(`Total tools: ${toolsResult.tools.length}`);
toolsResult.tools.forEach((tool, index) => {
console.log(`${index + 1}. ${tool.name}: ${tool.description || 'No description'}`);
});
// List available resources
console.log("\n=== Available Resources ===");
let resourcesResult: any = { resources: [] };
try {
resourcesResult = await client.listResources();
console.log(`Total resources: ${resourcesResult.resources.length}`);
resourcesResult.resources.forEach((resource: any, index: number) => {
console.log(`${index + 1}. ${resource.uriPattern || resource.uri}: ${resource.description || 'No description'}`);
});
if (resourcesResult.resources.length === 0) {
console.warn("WARNING: No resources returned by listResources. This may indicate missing list callbacks in the MCP server resource registration.");
console.warn("Try these common resource URIs manually:");
[
'jira://issues',
'jira://projects',
'jira://boards',
'confluence://pages',
'confluence://spaces'
].forEach((uri, idx) => {
console.log(` ${idx + 1}. ${uri}`);
});
}
} catch (error) {
console.log("Error listing resources:", error instanceof Error ? error.message : String(error));
}
// Group tools by category
console.log("\n=== Tools by Category ===");
const toolsByCategory: Record<string, any[]> = {};
toolsResult.tools.forEach(tool => {
let category = "Other";
if (tool.name.startsWith("create") || tool.name.startsWith("update") ||
tool.name.startsWith("delete") || tool.name.startsWith("get")) {
if (tool.name.toLowerCase().includes("issue") || tool.name.toLowerCase().includes("sprint") ||
tool.name.toLowerCase().includes("board") || tool.name.toLowerCase().includes("filter")) {
category = "Jira";
} else if (tool.name.toLowerCase().includes("page") || tool.name.toLowerCase().includes("comment") ||
tool.name.toLowerCase().includes("space")) {
category = "Confluence";
}
}
if (!toolsByCategory[category]) toolsByCategory[category] = [];
toolsByCategory[category].push(tool);
});
Object.entries(toolsByCategory).forEach(([category, tools]) => {
console.log(`\n${category} Tools (${tools.length}):`);
tools.forEach((tool, index) => {
console.log(` ${index + 1}. ${tool.name}`);
});
});
// Group resources by category
console.log("\n=== Resources by Category ===");
const resourcesByCategory: Record<string, any[]> = {};
resourcesResult.resources.forEach((resource: any) => {
let category = "Other";
const uri = resource.uriPattern || resource.uri || "";
if (uri.startsWith("jira://")) {
category = "Jira";
} else if (uri.startsWith("confluence://")) {
category = "Confluence";
}
if (!resourcesByCategory[category]) resourcesByCategory[category] = [];
resourcesByCategory[category].push(resource);
});
Object.entries(resourcesByCategory).forEach(([category, resources]) => {
console.log(`\n${category} Resources (${resources.length}):`);
resources.forEach((resource: any, index: number) => {
const uri = resource.uriPattern || resource.uri || "";
console.log(` ${index + 1}. ${uri}`);
});
});
// Show details for some important tools
console.log("\n=== Tool Details ===");
const toolsToInspect = ["createIssue", "updatePage", "addComment"];
for (const toolName of toolsToInspect) {
const tool = toolsResult.tools.find(t => t.name === toolName);
if (tool) {
console.log(`\nTool: ${tool.name}`);
console.log(`Description: ${tool.description || 'No description'}`);
console.log("Input Schema:", JSON.stringify(tool.inputSchema, null, 2));
}
}
await client.close();
console.log("\nDone.");
}
main();
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import path from 'path';
import { fileURLToPath } from "url";
import fs from "fs";
// Get current file path
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Load environment variables from .env
function loadEnv(): Record<string, string> {
try {
const envFile = path.resolve(process.cwd(), '.env');
const envContent = fs.readFileSync(envFile, 'utf8');
const envVars: Record<string, string> = {};
envContent.split('\n').forEach(line => {
if (line.trim().startsWith('#') || !line.trim()) return;
const [key, ...valueParts] = line.split('=');
if (key && valueParts.length > 0) {
const value = valueParts.join('=');
envVars[key.trim()] = value.trim();
}
});
return envVars;
} catch (error) {
console.error("Error loading .env file:", error);
return {};
}
}
// Print only response data
function printResourceMetaAndSchema(res: any) {
if (res.contents && res.contents.length > 0) {
const content = res.contents[0];
// COMMENTED OUT: Metadata and schema printing
// // Print metadata if exists
// if (content.metadata) {
// console.log("Metadata:", content.metadata);
// }
// // Print schema if exists
// if (content.schema) {
// console.log("Schema:", JSON.stringify(content.schema, null, 2));
// }
// Try to parse text if exists
if (content.text) {
try {
const data = JSON.parse(String(content.text));
console.log("Response Data:", JSON.stringify(data, null, 2));
} catch (e) {
console.log("Raw Response:", content.text);
}
}
}
}
async function main() {
const client = new Client({
name: "mcp-atlassian-test-client-confluence-pages",
version: "1.0.0"
});
// Path to MCP server
const serverPath = "/Users/phucnt/Workspace/mcp-jira-server/dist/index.js";
// Load environment variables
const envVars = loadEnv();
const processEnv: Record<string, string> = {};
Object.keys(process.env).forEach(key => {
if (process.env[key] !== undefined) {
processEnv[key] = process.env[key] as string;
}
});
// Initialize transport
const transport = new StdioClientTransport({
command: "node",
args: [serverPath],
env: {
...processEnv,
...envVars
}
});
// Connect to server
console.log("Connecting to MCP server...");
await client.connect(transport);
console.log("\n=== Test Confluence Pages Resource ===");
// Change these values to match your environment if needed
const pageId = "19431426"; // Home page id mới cho space AWA1
const spaceKey = "AWA1"; // Space key mới
const resourceUris = [
`confluence://pages/${pageId}`,
`confluence://spaces/${spaceKey}/pages`,
`confluence://pages/${pageId}/children`,
`confluence://pages/${pageId}/comments`,
`confluence://pages/${pageId}/versions`,
`confluence://pages/${pageId}/ancestors`,
`confluence://pages/${pageId}/attachments`
];
for (const uri of resourceUris) {
try {
console.log(`\nResource: ${uri}`);
const res = await client.readResource({ uri });
if (uri.includes("?cql=")) {
const pagesData = JSON.parse(String(res.contents[0].text));
console.log("Number of pages from CQL:", pagesData.pages?.length || 0);
} else if (uri.includes("/children")) {
const childrenData = JSON.parse(String(res.contents[0].text));
console.log("Number of children:", childrenData.children?.length || 0);
} else if (uri.includes("/comments")) {
const commentsData = JSON.parse(String(res.contents[0].text));
console.log("Number of comments:", commentsData.comments?.length || 0);
} else if (uri.includes("/versions")) {
const versionsData = JSON.parse(String(res.contents[0].text));
console.log("Number of versions:", versionsData.versions?.length || 0);
} else if (uri.includes("/ancestors")) {
const ancestorsData = JSON.parse(String(res.contents[0].text));
console.log("Ancestors:", JSON.stringify(ancestorsData.ancestors, null, 2));
} else if (uri.includes("/attachments")) {
const attachmentsData = JSON.parse(String(res.contents[0].text));
console.log("Number of attachments:", attachmentsData.attachments?.length || 0);
}
printResourceMetaAndSchema(res);
} catch (e) {
console.error(`Resource ${uri} error:`, e instanceof Error ? e.message : e);
}
}
console.log("\n=== Finished testing Confluence Pages Resource! ===");
await client.close();
}
main();
\ No newline at end of file
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import path from 'path';
import { fileURLToPath } from "url";
import fs from "fs";
// Get current file path
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Load environment variables from .env
function loadEnv(): Record<string, string> {
try {
const envFile = path.resolve(process.cwd(), '.env');
const envContent = fs.readFileSync(envFile, 'utf8');
const envVars: Record<string, string> = {};
envContent.split('\n').forEach(line => {
if (line.trim().startsWith('#') || !line.trim()) return;
const [key, ...valueParts] = line.split('=');
if (key && valueParts.length > 0) {
const value = valueParts.join('=');
envVars[key.trim()] = value.trim();
}
});
return envVars;
} catch (error) {
console.error("Error loading .env file:", error);
return {};
}
}
// Print metadata and schema
function printResourceMetaAndSchema(res: any) {
if (res.contents && res.contents.length > 0) {
const content = res.contents[0];
// Print metadata if exists
if (content.metadata) {
console.log("Metadata:", content.metadata);
}
// Print schema if exists
if (content.schema) {
console.log("Schema:", JSON.stringify(content.schema, null, 2));
}
// Try to parse text if exists
if (content.text) {
try {
const data = JSON.parse(String(content.text));
if (Array.isArray(data)) {
console.log("Data (array, first element):", data[0]);
} else if (typeof data === 'object') {
console.log("Data (object):", data);
} else {
console.log("Data:", data);
}
} catch {
console.log("Cannot parse text.");
}
}
}
}
async function main() {
const client = new Client({
name: "mcp-atlassian-test-client-confluence-spaces",
version: "1.0.0"
});
// Path to MCP server
const serverPath = "/Users/phucnt/Workspace/mcp-jira-server/dist/index.js";
// Load environment variables
const envVars = loadEnv();
const processEnv: Record<string, string> = {};
Object.keys(process.env).forEach(key => {
if (process.env[key] !== undefined) {
processEnv[key] = process.env[key] as string;
}
});
// Initialize transport
const transport = new StdioClientTransport({
command: "node",
args: [serverPath],
env: {
...processEnv,
...envVars
}
});
// Connect to server
console.log("Connecting to MCP server...");
await client.connect(transport);
console.log("\n=== Test Confluence Spaces Resource ===");
// Nếu có biến spaceKey hoặc pageId, hãy cập nhật:
const spaceKey = "AWA1"; // Space key mới
const homePageId = "19464453"; // Home page id mới
const resourceUris = [
`confluence://spaces`,
`confluence://spaces/${spaceKey}`,
`confluence://spaces/${spaceKey}/pages`
];
for (const uri of resourceUris) {
try {
console.log(`\nResource: ${uri}`);
const res = await client.readResource({ uri });
if (uri === "confluence://spaces") {
const spacesData = JSON.parse(String(res.contents[0].text));
console.log("Number of spaces:", spacesData.spaces?.length || 0);
} else if (uri.includes("/pages")) {
const pagesData = JSON.parse(String(res.contents[0].text));
console.log("Number of pages:", pagesData.pages?.length || 0);
}
printResourceMetaAndSchema(res);
} catch (e) {
console.error(`Resource ${uri} error:`, e instanceof Error ? e.message : e);
}
}
console.log("\n=== Finished testing Confluence Spaces Resource! ===");
await client.close();
}
main();
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment