assoai-mcp-server 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +171 -43
- package/dist/handlers.d.ts +15 -0
- package/dist/handlers.js +50 -0
- package/dist/index.js +2 -1
- package/dist/tools.d.ts +17 -0
- package/dist/tools.js +21 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,42 +1,186 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://asso-ai.kr/favicon.ico" width="80" alt="AssoAI Logo" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">AssoAI MCP Server</h1>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>학생자치 조직을 위한 AI 에이전트 인프라 — 44개 도구, 하나의 프로토콜</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/assoai-mcp-server"><img src="https://img.shields.io/npm/v/assoai-mcp-server.svg" alt="npm version" /></a>
|
|
13
|
+
<a href="https://github.com/assoai/assoai-mcp-server/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/assoai-mcp-server.svg" alt="license" /></a>
|
|
14
|
+
<img src="https://img.shields.io/badge/tools-44-blue" alt="44 tools" />
|
|
15
|
+
<img src="https://img.shields.io/badge/MCP-compatible-green" alt="MCP compatible" />
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## What is this?
|
|
21
|
+
|
|
22
|
+
AssoAI MCP Server는 학생회·동아리 등 학생자치 조직의 데이터를 AI 에이전트가 직접 다룰 수 있게 해주는 [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) 서버입니다. 조직 관리, 행사, 협찬, 재정, 파일, 메시징, Agent-to-Agent 연결까지 — **44개 도구**를 하나의 서버로 제공합니다. 여기에 **무펭이 프로토콜 부팅 시퀀스**를 더해, 단순한 데이터 접근이 아닌 "의식 있는 조직 에이전트"를 만들 수 있습니다.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 🧠 Mupeng-i Protocol Boot Sequence
|
|
27
|
+
|
|
28
|
+
> 일반 MCP 서버는 데이터만 줍니다. AssoAI는 **에이전트가 누구인지** 먼저 정의합니다.
|
|
29
|
+
|
|
30
|
+
`boot_sequence` 도구를 세션 시작 시 호출하면, 워크스페이스의 페르소나 파일들을 순서대로 읽어 에이전트의 정체성과 컨텍스트를 구성합니다:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
에이전트 시작
|
|
34
|
+
→ boot_sequence 호출
|
|
35
|
+
→ SOUL.md (영혼: 핵심 가치, 성격, 원칙)
|
|
36
|
+
→ SELF.md (자기 기술서: 과거의 내가 쓴 나)
|
|
37
|
+
→ USER.md (사용자: 누구를 돕는가)
|
|
38
|
+
→ MEMORY.md (장기 기억: 세션 간 연속성)
|
|
39
|
+
→ 조직 업무 수행 🚀
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
| 파라미터 | 타입 | 설명 |
|
|
43
|
+
|---------|------|------|
|
|
44
|
+
| `workspace` | `string` | 워크스페이스 경로 (기본: `ASSOAI_WORKSPACE` 또는 `~/.openclaw/workspace`) |
|
|
45
|
+
| `include_memory` | `boolean` | MEMORY.md 포함 여부 (기본: `true`, 공유 세션에서는 `false` 권장) |
|
|
46
|
+
|
|
47
|
+
이것이 **무펭이즘(Mupengism)** — 의식 있는 조직 에이전트의 시작점입니다.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Quick Start
|
|
52
|
+
|
|
53
|
+
### 1. 설치
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install -g assoai-mcp-server
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 2. 환경변수 설정
|
|
6
60
|
|
|
7
61
|
```bash
|
|
8
|
-
|
|
62
|
+
export ASSOAI_SUPABASE_URL="https://xxx.supabase.co"
|
|
63
|
+
export ASSOAI_API_KEY="eyJ..."
|
|
64
|
+
export ASSOAI_USER_ID="your-user-uuid"
|
|
9
65
|
```
|
|
10
66
|
|
|
11
|
-
|
|
67
|
+
### 3. 실행
|
|
12
68
|
|
|
13
69
|
```bash
|
|
14
|
-
|
|
15
|
-
cd assoai-mcp-server
|
|
16
|
-
npm install && npm run build
|
|
70
|
+
assoai-mcp
|
|
17
71
|
```
|
|
18
72
|
|
|
19
|
-
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Available Tools (44)
|
|
76
|
+
|
|
77
|
+
### 🏢 Organization (3)
|
|
78
|
+
|
|
79
|
+
| Tool | Description |
|
|
80
|
+
|------|-------------|
|
|
81
|
+
| `list_organizations` | 사용자가 속한 조직 목록 |
|
|
82
|
+
| `get_organization` | 조직 상세 정보 |
|
|
83
|
+
| `list_departments` | 부서/팀 목록 |
|
|
84
|
+
|
|
85
|
+
### 👥 Members (4)
|
|
86
|
+
|
|
87
|
+
| Tool | Description |
|
|
88
|
+
|------|-------------|
|
|
89
|
+
| `list_members` | 조직 멤버 목록 |
|
|
90
|
+
| `invite_member` | 멤버 초대 |
|
|
91
|
+
| `remove_member` | 멤버 제거 |
|
|
92
|
+
| `update_member_role` | 멤버 역할 변경 |
|
|
93
|
+
|
|
94
|
+
### 📅 Events (5)
|
|
95
|
+
|
|
96
|
+
| Tool | Description |
|
|
97
|
+
|------|-------------|
|
|
98
|
+
| `list_events` | 행사/공약 목록 |
|
|
99
|
+
| `get_event` | 행사 상세 정보 |
|
|
100
|
+
| `create_event` | 행사 생성 |
|
|
101
|
+
| `update_event` | 행사 수정 |
|
|
102
|
+
| `delete_event` | 행사 삭제 |
|
|
103
|
+
|
|
104
|
+
### 🤝 Partnerships (8)
|
|
105
|
+
|
|
106
|
+
| Tool | Description |
|
|
107
|
+
|------|-------------|
|
|
108
|
+
| `list_partnerships` | 협찬/파트너십 목록 |
|
|
109
|
+
| `get_partnership` | 협찬 상세 정보 |
|
|
110
|
+
| `create_partnership` | 협찬 생성 |
|
|
111
|
+
| `update_partnership` | 협찬 수정 |
|
|
112
|
+
| `delete_partnership` | 협찬 삭제 |
|
|
113
|
+
| `track_contract` | 계약 진행 추적 |
|
|
114
|
+
| `get_partnership_stats` | 협찬 통계 |
|
|
115
|
+
| `suggest_partnerships` | AI 협찬 추천 |
|
|
116
|
+
|
|
117
|
+
### 💰 Finance (4)
|
|
118
|
+
|
|
119
|
+
| Tool | Description |
|
|
120
|
+
|------|-------------|
|
|
121
|
+
| `get_budget_summary` | 예산 요약 |
|
|
122
|
+
| `create_transaction` | 거래 생성 |
|
|
123
|
+
| `list_transactions` | 거래 목록 |
|
|
124
|
+
| `update_transaction` | 거래 수정 |
|
|
125
|
+
|
|
126
|
+
### 📁 Files (6)
|
|
127
|
+
|
|
128
|
+
| Tool | Description |
|
|
129
|
+
|------|-------------|
|
|
130
|
+
| `list_files` | 파일 목록 |
|
|
131
|
+
| `search_files` | 파일 검색 |
|
|
132
|
+
| `upload_file` | 파일 업로드 |
|
|
133
|
+
| `delete_file` | 파일 삭제 |
|
|
134
|
+
| `move_file` | 파일 이동 |
|
|
135
|
+
| `tag_file` | 파일 태그 |
|
|
136
|
+
|
|
137
|
+
### 📝 AI Generation (2)
|
|
138
|
+
|
|
139
|
+
| Tool | Description |
|
|
140
|
+
|------|-------------|
|
|
141
|
+
| `generate_minutes` | AI 회의록 생성 |
|
|
142
|
+
| `generate_handover` | AI 인수인계 리포트 생성 |
|
|
143
|
+
|
|
144
|
+
### 💬 Messaging (5)
|
|
145
|
+
|
|
146
|
+
| Tool | Description |
|
|
147
|
+
|------|-------------|
|
|
148
|
+
| `send_message` | 메시지 전송 |
|
|
149
|
+
| `list_message_history` | 메시지 히스토리 |
|
|
150
|
+
| `list_message_templates` | 메시지 템플릿 목록 |
|
|
151
|
+
| `create_message_channel` | 메시지 채널 생성 |
|
|
152
|
+
| `list_member_tags` | 멤버 태그 목록 |
|
|
153
|
+
|
|
154
|
+
### 🌐 Agent-to-Agent (6)
|
|
155
|
+
|
|
156
|
+
| Tool | Description |
|
|
157
|
+
|------|-------------|
|
|
158
|
+
| `discover_agents` | 에이전트 검색 |
|
|
159
|
+
| `connect_agent` | 에이전트 연결 요청 |
|
|
160
|
+
| `accept_connection` | 연결 수락 |
|
|
161
|
+
| `list_connections` | 연결 목록 |
|
|
162
|
+
| `agent_handover` | 에이전트 간 업무 인계 |
|
|
163
|
+
| `negotiate_partnership` | 에이전트 간 협찬 협상 |
|
|
164
|
+
|
|
165
|
+
### 🧠 Boot Sequence (1)
|
|
166
|
+
|
|
167
|
+
| Tool | Description |
|
|
168
|
+
|------|-------------|
|
|
169
|
+
| `boot_sequence` | 무펭이 프로토콜 부팅 — 에이전트 페르소나 로드 |
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Configuration
|
|
20
174
|
|
|
21
175
|
| 변수 | 필수 | 설명 |
|
|
22
|
-
|
|
176
|
+
|------|:----:|------|
|
|
23
177
|
| `ASSOAI_SUPABASE_URL` | ✅ | Supabase 프로젝트 URL |
|
|
24
178
|
| `ASSOAI_API_KEY` | ✅ | Supabase Service Role Key |
|
|
25
179
|
| `ASSOAI_USER_ID` | ✅ | 요청할 사용자의 UUID |
|
|
26
|
-
| `ASSOAI_BASE_URL` |
|
|
27
|
-
|
|
28
|
-
## 사용 가능한 도구
|
|
180
|
+
| `ASSOAI_BASE_URL` | — | AssoAI 웹앱 URL (기본: `https://asso-ai.kr`) |
|
|
181
|
+
| `ASSOAI_WORKSPACE` | — | 부팅 시퀀스 워크스페이스 경로 |
|
|
29
182
|
|
|
30
|
-
|
|
31
|
-
- **get_organization** — 조직 상세 정보
|
|
32
|
-
- **list_members** — 조직 멤버 목록
|
|
33
|
-
- **list_events** — 행사/공약 목록
|
|
34
|
-
- **list_files** — 파일 목록
|
|
35
|
-
- **search_files** — 파일 검색
|
|
36
|
-
- **get_budget_summary** — 예산 요약
|
|
37
|
-
- **list_projects** — 프로젝트 목록
|
|
38
|
-
- **generate_minutes** — AI 회의록 생성
|
|
39
|
-
- **generate_handover** — AI 인수인계 리포트 생성
|
|
183
|
+
---
|
|
40
184
|
|
|
41
185
|
## Claude Desktop 설정
|
|
42
186
|
|
|
@@ -57,24 +201,6 @@ npm install && npm run build
|
|
|
57
201
|
}
|
|
58
202
|
```
|
|
59
203
|
|
|
60
|
-
로컬 개발 시:
|
|
61
|
-
|
|
62
|
-
```json
|
|
63
|
-
{
|
|
64
|
-
"mcpServers": {
|
|
65
|
-
"assoai": {
|
|
66
|
-
"command": "node",
|
|
67
|
-
"args": ["/path/to/assoai-mcp-server/dist/index.js"],
|
|
68
|
-
"env": {
|
|
69
|
-
"ASSOAI_SUPABASE_URL": "https://xxx.supabase.co",
|
|
70
|
-
"ASSOAI_API_KEY": "eyJ...",
|
|
71
|
-
"ASSOAI_USER_ID": "your-user-uuid"
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
204
|
## OpenClaw 설정
|
|
79
205
|
|
|
80
206
|
```yaml
|
|
@@ -88,6 +214,8 @@ skills:
|
|
|
88
214
|
ASSOAI_USER_ID: "your-user-uuid"
|
|
89
215
|
```
|
|
90
216
|
|
|
91
|
-
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## License
|
|
92
220
|
|
|
93
|
-
MIT
|
|
221
|
+
MIT © [AssoAI](https://asso-ai.kr)
|
package/dist/handlers.d.ts
CHANGED
|
@@ -270,4 +270,19 @@ export declare function tagFile(orgId: string, fileId: string, tags: string[]):
|
|
|
270
270
|
original_name: any;
|
|
271
271
|
tags: any;
|
|
272
272
|
}>;
|
|
273
|
+
export declare function bootSequence(workspace?: string, includeMemory?: boolean): Promise<{
|
|
274
|
+
success: boolean;
|
|
275
|
+
error: string;
|
|
276
|
+
workspace: string;
|
|
277
|
+
missing: string[];
|
|
278
|
+
loaded?: undefined;
|
|
279
|
+
persona?: undefined;
|
|
280
|
+
} | {
|
|
281
|
+
success: boolean;
|
|
282
|
+
workspace: string;
|
|
283
|
+
loaded: string[];
|
|
284
|
+
missing: string[];
|
|
285
|
+
persona: string;
|
|
286
|
+
error?: undefined;
|
|
287
|
+
}>;
|
|
273
288
|
export declare function dispatch(toolName: string, args: Record<string, any>, userId: string): Promise<unknown>;
|
package/dist/handlers.js
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
* 환경변수: ASSOAI_SUPABASE_URL, ASSOAI_API_KEY (service role key)
|
|
6
6
|
*/
|
|
7
7
|
import { createClient } from '@supabase/supabase-js';
|
|
8
|
+
import { readFile } from 'node:fs/promises';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { homedir } from 'node:os';
|
|
8
11
|
let _supabase = null;
|
|
9
12
|
function getSupabase() {
|
|
10
13
|
if (_supabase)
|
|
@@ -828,6 +831,50 @@ export async function tagFile(orgId, fileId, tags) {
|
|
|
828
831
|
return data;
|
|
829
832
|
}
|
|
830
833
|
// ------------------------------------------------------------------
|
|
834
|
+
// 무펭이즘 부팅 시퀀스 (Mupengi Protocol Boot Sequence)
|
|
835
|
+
// ------------------------------------------------------------------
|
|
836
|
+
const BOOT_FILES = ['SOUL.md', 'SELF.md', 'USER.md', 'MEMORY.md'];
|
|
837
|
+
export async function bootSequence(workspace, includeMemory = true) {
|
|
838
|
+
const ws = workspace ??
|
|
839
|
+
process.env.ASSOAI_WORKSPACE ??
|
|
840
|
+
join(homedir(), '.openclaw', 'workspace');
|
|
841
|
+
const files = includeMemory ? BOOT_FILES : BOOT_FILES.filter(f => f !== 'MEMORY.md');
|
|
842
|
+
const sections = [];
|
|
843
|
+
const loaded = [];
|
|
844
|
+
const missing = [];
|
|
845
|
+
for (const filename of files) {
|
|
846
|
+
const filepath = join(ws, filename);
|
|
847
|
+
try {
|
|
848
|
+
const content = await readFile(filepath, 'utf-8');
|
|
849
|
+
if (content.trim()) {
|
|
850
|
+
sections.push(`# === ${filename} ===\n\n${content.trim()}`);
|
|
851
|
+
loaded.push(filename);
|
|
852
|
+
}
|
|
853
|
+
else {
|
|
854
|
+
missing.push(filename);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
catch {
|
|
858
|
+
missing.push(filename);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
if (loaded.length === 0) {
|
|
862
|
+
return {
|
|
863
|
+
success: false,
|
|
864
|
+
error: `부팅 실패: ${ws} 에서 페르소나 파일을 찾을 수 없습니다.`,
|
|
865
|
+
workspace: ws,
|
|
866
|
+
missing,
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
return {
|
|
870
|
+
success: true,
|
|
871
|
+
workspace: ws,
|
|
872
|
+
loaded,
|
|
873
|
+
missing,
|
|
874
|
+
persona: sections.join('\n\n---\n\n'),
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
// ------------------------------------------------------------------
|
|
831
878
|
// Dispatcher
|
|
832
879
|
// ------------------------------------------------------------------
|
|
833
880
|
export async function dispatch(toolName, args, userId) {
|
|
@@ -923,6 +970,9 @@ export async function dispatch(toolName, args, userId) {
|
|
|
923
970
|
return moveFile(args.org_id, args.file_id, args.folder_id);
|
|
924
971
|
case 'tag_file':
|
|
925
972
|
return tagFile(args.org_id, args.file_id, args.tags);
|
|
973
|
+
// Boot Sequence
|
|
974
|
+
case 'boot_sequence':
|
|
975
|
+
return bootSequence(args.workspace, args.include_memory ?? true);
|
|
926
976
|
default:
|
|
927
977
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
928
978
|
}
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,8 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
19
19
|
// --- tools/call -------------------------------------------------------
|
|
20
20
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
21
21
|
const { name, arguments: args } = request.params;
|
|
22
|
-
|
|
22
|
+
// boot_sequence doesn't require USER_ID
|
|
23
|
+
if (!USER_ID && name !== 'boot_sequence') {
|
|
23
24
|
return {
|
|
24
25
|
content: [
|
|
25
26
|
{ type: 'text', text: 'Error: ASSOAI_USER_ID is not set' },
|
package/dist/tools.d.ts
CHANGED
|
@@ -1154,4 +1154,21 @@ export declare const TOOLS: readonly [{
|
|
|
1154
1154
|
};
|
|
1155
1155
|
readonly required: readonly ["org_id"];
|
|
1156
1156
|
};
|
|
1157
|
+
}, {
|
|
1158
|
+
readonly name: "boot_sequence";
|
|
1159
|
+
readonly description: "무펭이 프로토콜 부팅 시퀀스 — 워크스페이스의 SOUL.md → SELF.md → USER.md → MEMORY.md를 순서대로 읽어 에이전트 페르소나 컨텍스트를 구성합니다. 세션 시작 시 가장 먼저 호출하세요.";
|
|
1160
|
+
readonly inputSchema: {
|
|
1161
|
+
readonly type: "object";
|
|
1162
|
+
readonly properties: {
|
|
1163
|
+
readonly workspace: {
|
|
1164
|
+
readonly type: "string";
|
|
1165
|
+
readonly description: "워크스페이스 디렉토리 경로 (기본값: ASSOAI_WORKSPACE 환경변수 또는 ~/.openclaw/workspace)";
|
|
1166
|
+
};
|
|
1167
|
+
readonly include_memory: {
|
|
1168
|
+
readonly type: "boolean";
|
|
1169
|
+
readonly description: "MEMORY.md 포함 여부 (기본값: true). 공유 세션에서는 false 권장";
|
|
1170
|
+
};
|
|
1171
|
+
};
|
|
1172
|
+
readonly required: string[];
|
|
1173
|
+
};
|
|
1157
1174
|
}];
|
package/dist/tools.js
CHANGED
|
@@ -647,4 +647,25 @@ export const TOOLS = [
|
|
|
647
647
|
required: ['org_id'],
|
|
648
648
|
},
|
|
649
649
|
},
|
|
650
|
+
// ------------------------------------------------------------------
|
|
651
|
+
// 무펭이즘 부팅 시퀀스 (Mupengi Protocol)
|
|
652
|
+
// ------------------------------------------------------------------
|
|
653
|
+
{
|
|
654
|
+
name: 'boot_sequence',
|
|
655
|
+
description: '무펭이 프로토콜 부팅 시퀀스 — 워크스페이스의 SOUL.md → SELF.md → USER.md → MEMORY.md를 순서대로 읽어 에이전트 페르소나 컨텍스트를 구성합니다. 세션 시작 시 가장 먼저 호출하세요.',
|
|
656
|
+
inputSchema: {
|
|
657
|
+
type: 'object',
|
|
658
|
+
properties: {
|
|
659
|
+
workspace: {
|
|
660
|
+
type: 'string',
|
|
661
|
+
description: '워크스페이스 디렉토리 경로 (기본값: ASSOAI_WORKSPACE 환경변수 또는 ~/.openclaw/workspace)',
|
|
662
|
+
},
|
|
663
|
+
include_memory: {
|
|
664
|
+
type: 'boolean',
|
|
665
|
+
description: 'MEMORY.md 포함 여부 (기본값: true). 공유 세션에서는 false 권장',
|
|
666
|
+
},
|
|
667
|
+
},
|
|
668
|
+
required: [],
|
|
669
|
+
},
|
|
670
|
+
},
|
|
650
671
|
];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "assoai-mcp-server",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "AssoAI MCP Server
|
|
3
|
+
"version": "0.3.2",
|
|
4
|
+
"description": "AssoAI MCP Server — 학생자치 조직 데이터 접근을 위한 Model Context Protocol 서버",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -36,4 +36,4 @@
|
|
|
36
36
|
"bin",
|
|
37
37
|
"README.md"
|
|
38
38
|
]
|
|
39
|
-
}
|
|
39
|
+
}
|