# Directory Structure
```
├── mcp-server.py
├── mcp.json
├── README.md
├── requirements.txt
└── test_client.py
```
# Files
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
1 | # confluence-chat-mcp-service
```
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
```
1 | python-dotenv==1.0.0
2 | requests==2.31.0 
```
--------------------------------------------------------------------------------
/test_client.py:
--------------------------------------------------------------------------------
```python
 1 | import json
 2 | import sys
 3 | 
 4 | def send_request():
 5 |     request = {
 6 |         "jsonrpc": "2.0",
 7 |         "method": "expand_content_tool",
 8 |         "params": {
 9 |             "header": "Understanding Animal Food Chains",
10 |             "content": "Create a comprehensive guide about animal food chains."
11 |         }
12 |     }
13 |     print(json.dumps(request))
14 |     sys.stdout.flush()
15 | 
16 | if __name__ == "__main__":
17 |     send_request() 
```
--------------------------------------------------------------------------------
/mcp.json:
--------------------------------------------------------------------------------
```json
 1 | {
 2 |   "name": "MyServer",
 3 |   "version": "1.0.0",
 4 |   "description": "A simple MCP server",
 5 |   "args": ["mcp-server.py"],
 6 |   "tools": [
 7 |     {
 8 |       "name": "expand_content_tool",
 9 |       "description": "Expands content and updates Confluence page",
10 |       "parameters": {
11 |         "type": "object",
12 |         "properties": {
13 |           "header": {
14 |             "type": "string",
15 |             "description": "The header for the content section"
16 |           },
17 |           "original_content": {
18 |             "type": "string",
19 |             "description": "The original content to be expanded"
20 |           },
21 |           "expanded_content": {
22 |             "type": "string",
23 |             "description": "The expanded content"
24 |           }
25 |         },
26 |         "required": ["header", "original_content", "expanded_content"]
27 |       }
28 |     }
29 |   ]
30 | }
```
--------------------------------------------------------------------------------
/mcp-server.py:
--------------------------------------------------------------------------------
```python
  1 | import json
  2 | import sys
  3 | import os
  4 | from dotenv import load_dotenv
  5 | import requests
  6 | import logging
  7 | 
  8 | # Configure logging
  9 | logging.basicConfig(level=logging.DEBUG)
 10 | logger = logging.getLogger(__name__)
 11 | 
 12 | # Load environment variables
 13 | load_dotenv()
 14 | 
 15 | # Confluence API configuration
 16 | CONFLUENCE_URL = os.getenv("CONFLUENCE_URL")
 17 | CONFLUENCE_USERNAME = os.getenv("CONFLUENCE_USERNAME")
 18 | CONFLUENCE_API_TOKEN = os.getenv("CONFLUENCE_API_TOKEN")
 19 | PAGE_ID = os.getenv("PAGE_ID")
 20 | 
 21 | def generate_auth_header():
 22 |     """Generate the authentication header for Confluence API."""
 23 |     return f"Basic {CONFLUENCE_USERNAME}:{CONFLUENCE_API_TOKEN}"
 24 | 
 25 | def expand_content(header, content):
 26 |     """Expand the content and update Confluence page."""
 27 |     try:
 28 |         # Generate authentication header
 29 |         auth_header = generate_auth_header()
 30 |         logger.debug("Generated authentication header")
 31 | 
 32 |         # Create new content
 33 |         new_content = f"""
 34 | h1. {header}
 35 | 
 36 | {content}
 37 | 
 38 | h2. Key Concepts
 39 | 
 40 | * Food Chain Definition
 41 | * Producers and Consumers
 42 | * Energy Flow
 43 | * Trophic Levels
 44 | 
 45 | h2. Examples
 46 | 
 47 | h3. Terrestrial Food Chain
 48 | * Grass → Grasshopper → Frog → Snake → Hawk
 49 | 
 50 | h3. Marine Food Chain
 51 | * Phytoplankton → Zooplankton → Small Fish → Large Fish → Shark
 52 | 
 53 | h2. Impact on Ecosystems
 54 | 
 55 | * Balance in Nature
 56 | * Environmental Factors
 57 | * Human Impact
 58 | """
 59 |         logger.debug("Created new content")
 60 | 
 61 |         # Update Confluence page
 62 |         update_url = f"{CONFLUENCE_URL}/rest/api/content/{PAGE_ID}"
 63 |         headers = {
 64 |             "Authorization": auth_header,
 65 |             "Content-Type": "application/json"
 66 |         }
 67 |         
 68 |         # Get current version
 69 |         response = requests.get(update_url, headers=headers)
 70 |         if response.status_code != 200:
 71 |             logger.error(f"Failed to get current version: {response.text}")
 72 |             return False
 73 |             
 74 |         current_version = response.json()["version"]["number"]
 75 |         logger.debug(f"Current version: {current_version}")
 76 | 
 77 |         # Update content
 78 |         update_data = {
 79 |             "version": {"number": current_version + 1},
 80 |             "title": header,
 81 |             "type": "page",
 82 |             "body": {
 83 |                 "storage": {
 84 |                     "value": new_content,
 85 |                     "representation": "wiki"
 86 |                 }
 87 |             }
 88 |         }
 89 | 
 90 |         response = requests.put(update_url, headers=headers, json=update_data)
 91 |         if response.status_code != 200:
 92 |             logger.error(f"Failed to update page: {response.text}")
 93 |             return False
 94 | 
 95 |         logger.info("Successfully updated Confluence page")
 96 |         return True
 97 | 
 98 |     except Exception as e:
 99 |         logger.error(f"Error expanding content: {str(e)}")
100 |         return False
101 | 
102 | def handle_request(request):
103 |     """Handle incoming JSON-RPC requests."""
104 |     try:
105 |         method = request.get("method")
106 |         params = request.get("params", {})
107 | 
108 |         if method == "expand_content_tool":
109 |             header = params.get("header")
110 |             content = params.get("content")
111 |             
112 |             if not header or not content:
113 |                 return {
114 |                     "jsonrpc": "2.0",
115 |                     "error": {
116 |                         "code": -32602,
117 |                         "message": "Invalid parameters"
118 |                     }
119 |                 }
120 | 
121 |             success = expand_content(header, content)
122 |             
123 |             return {
124 |                 "jsonrpc": "2.0",
125 |                 "result": {
126 |                     "success": success,
127 |                     "message": "Content expanded and updated successfully" if success else "Failed to expand content"
128 |                 }
129 |             }
130 | 
131 |         else:
132 |             return {
133 |                 "jsonrpc": "2.0",
134 |                 "error": {
135 |                     "code": -32601,
136 |                     "message": "Method not found"
137 |                 }
138 |             }
139 | 
140 |     except Exception as e:
141 |         return {
142 |             "jsonrpc": "2.0",
143 |             "error": {
144 |                 "code": -32000,
145 |                 "message": str(e)
146 |             }
147 |         }
148 | 
149 | def main():
150 |     """Main server loop."""
151 |     logger.info("Starting MCP server...")
152 |     
153 |     # Verify environment variables
154 |     required_vars = ["CONFLUENCE_URL", "CONFLUENCE_USERNAME", "CONFLUENCE_API_TOKEN", "PAGE_ID"]
155 |     missing_vars = [var for var in required_vars if not os.getenv(var)]
156 |     
157 |     if missing_vars:
158 |         logger.error(f"Missing required environment variables: {', '.join(missing_vars)}")
159 |         return
160 | 
161 |     logger.info("Environment check passed")
162 | 
163 |     while True:
164 |         try:
165 |             # Read request from stdin
166 |             request_line = sys.stdin.readline()
167 |             if not request_line:
168 |                 break
169 | 
170 |             request = json.loads(request_line)
171 |             logger.debug(f"Received request: {request}")
172 | 
173 |             # Handle request
174 |             response = handle_request(request)
175 |             
176 |             # Send response to stdout
177 |             print(json.dumps(response))
178 |             sys.stdout.flush()
179 | 
180 |         except json.JSONDecodeError:
181 |             logger.error("Invalid JSON received")
182 |             continue
183 |         except Exception as e:
184 |             logger.error(f"Error processing request: {str(e)}")
185 |             continue
186 | 
187 | if __name__ == "__main__":
188 |     main() 
```