aiquila-mcp 0.3.3 → 0.3.5

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # AIquila MCP Server
2
2
 
3
- MCP (Model Context Protocol) server that gives any MCP client full access to your Nextcloud instance — files, calendar, tasks, contacts, mail, talk, maps, bookmarks, notes, and more. 198 tools across 31 categories.
3
+ MCP (Model Context Protocol) server that gives any MCP client full access to your Nextcloud instance — files, calendar, tasks, contacts, mail, talk, maps, bookmarks, notes, polls, forms, and more. 244 tools across 33 categories.
4
4
 
5
5
  ## Quick Start
6
6
 
@@ -73,11 +73,13 @@ See the [Docker setup guide](https://github.com/elgorro/aiquila/blob/main/docs/m
73
73
  | Talk | 10 |
74
74
  | Circles | 8 |
75
75
  | Bookmarks | 13 |
76
+ | Polls | 21 |
77
+ | Forms | 25 |
76
78
  | Assistant | 4 |
77
79
  | Translate | 1 |
78
80
  | User Status | 5 |
79
81
  | Notifications | 4 |
80
- | **Total** | **198** |
82
+ | **Total** | **244** |
81
83
 
82
84
  ## Configuration
83
85
 
@@ -0,0 +1,51 @@
1
+ // SPDX-License-Identifier: MIT
2
+ import { getNextcloudConfig } from '../tools/types.js';
3
+ import { logger } from '../logger.js';
4
+ import { ApiError } from './aiquila.js';
5
+ /**
6
+ * Make an authenticated request to the Nextcloud Forms REST API v3.
7
+ *
8
+ * Base path: /ocs/v2.php/apps/forms/api/v3
9
+ * Unwraps the OCS envelope and returns `ocs.data` directly.
10
+ * Throws {@link ApiError} on HTTP errors or non-success OCS status codes.
11
+ */
12
+ export async function fetchFormsAPI(endpoint, options = {}) {
13
+ const config = getNextcloudConfig();
14
+ const auth = Buffer.from(`${config.user}:${config.password}`).toString('base64');
15
+ let url = `${config.url}/ocs/v2.php/apps/forms/api/v3${endpoint}`;
16
+ if (options.queryParams) {
17
+ const params = new URLSearchParams(options.queryParams);
18
+ url += `?${params.toString()}`;
19
+ }
20
+ const headers = {
21
+ Authorization: `Basic ${auth}`,
22
+ 'OCS-APIRequest': 'true',
23
+ Accept: 'application/json',
24
+ };
25
+ let body;
26
+ if (options.body !== undefined) {
27
+ body = JSON.stringify(options.body);
28
+ headers['Content-Type'] = 'application/json';
29
+ }
30
+ const method = options.method ?? 'GET';
31
+ const t0 = Date.now();
32
+ const response = await fetch(url, { method, headers, body });
33
+ logger.trace({ method, url, status: response.status, ms: Date.now() - t0 }, '[forms] HTTP');
34
+ if (!response.ok) {
35
+ const text = await response.text();
36
+ throw new ApiError(response.status, response.statusText, text);
37
+ }
38
+ if (response.status === 204) {
39
+ return undefined;
40
+ }
41
+ const contentType = response.headers.get('content-type') ?? '';
42
+ if (!contentType.includes('application/json')) {
43
+ return undefined;
44
+ }
45
+ const json = (await response.json());
46
+ const code = json?.ocs?.meta?.statuscode;
47
+ if (code !== undefined && code !== 200 && code !== 100) {
48
+ throw new ApiError(code, json.ocs.meta.status ?? 'error', json.ocs.meta.message ?? '');
49
+ }
50
+ return json.ocs.data;
51
+ }
@@ -0,0 +1,44 @@
1
+ // SPDX-License-Identifier: MIT
2
+ import { getNextcloudConfig } from '../tools/types.js';
3
+ import { logger } from '../logger.js';
4
+ import { ApiError } from './aiquila.js';
5
+ /**
6
+ * Make an authenticated request to the Nextcloud Polls REST API v1.0.
7
+ *
8
+ * Base path: /index.php/apps/polls/api/v1.0
9
+ */
10
+ export async function fetchPollsAPI(endpoint, options = {}) {
11
+ const config = getNextcloudConfig();
12
+ const auth = Buffer.from(`${config.user}:${config.password}`).toString('base64');
13
+ let url = `${config.url}/index.php/apps/polls/api/v1.0${endpoint}`;
14
+ if (options.queryParams) {
15
+ const params = new URLSearchParams(options.queryParams);
16
+ url += `?${params.toString()}`;
17
+ }
18
+ const headers = {
19
+ Authorization: `Basic ${auth}`,
20
+ 'OCS-APIRequest': 'true',
21
+ Accept: 'application/json',
22
+ };
23
+ let body;
24
+ if (options.body !== undefined) {
25
+ body = JSON.stringify(options.body);
26
+ headers['Content-Type'] = 'application/json';
27
+ }
28
+ const method = options.method ?? 'GET';
29
+ const t0 = Date.now();
30
+ const response = await fetch(url, { method, headers, body });
31
+ logger.trace({ method, url, status: response.status, ms: Date.now() - t0 }, '[polls] HTTP');
32
+ if (!response.ok) {
33
+ const text = await response.text();
34
+ throw new ApiError(response.status, response.statusText, text);
35
+ }
36
+ if (response.status === 204) {
37
+ return undefined;
38
+ }
39
+ const contentType = response.headers.get('content-type') ?? '';
40
+ if (contentType.includes('application/json')) {
41
+ return (await response.json());
42
+ }
43
+ return undefined;
44
+ }
@@ -34,6 +34,8 @@ import { notificationsTools } from './tools/apps/notifications.js';
34
34
  import { trashTools } from './tools/apps/trash.js';
35
35
  import { versionsTools } from './tools/apps/versions.js';
36
36
  import { projectsTools } from './tools/apps/projects.js';
37
+ import { pollsTools } from './tools/apps/polls.js';
38
+ import { formsTools } from './tools/apps/forms.js';
37
39
  /**
38
40
  * Single source of truth for tool-to-Nextcloud-app mapping.
39
41
  *
@@ -72,6 +74,8 @@ export const TOOL_REGISTRY = [
72
74
  { category: 'talk', appIds: ['spreed'], tools: talkTools },
73
75
  { category: 'circles', appIds: ['circles'], tools: circlesTools },
74
76
  { category: 'bookmarks', appIds: ['bookmarks'], tools: bookmarksTools },
77
+ { category: 'polls', appIds: ['polls'], tools: pollsTools },
78
+ { category: 'forms', appIds: ['forms'], tools: formsTools },
75
79
  { category: 'assistant', appIds: ['assistant'], tools: assistantTools },
76
80
  { category: 'translate', appIds: ['text_translate', 'translate'], tools: translateTools },
77
81
  { category: 'user_status', appIds: ['user_status'], tools: userStatusTools },