outline-mcp-server 4.12.2 → 5.0.0
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 +28 -17
- package/build/index.js +52 -51
- package/build/tools/archiveDocument.js +7 -13
- package/build/tools/askDocuments.js +21 -35
- package/build/tools/createCollection.js +14 -29
- package/build/tools/createComment.js +13 -25
- package/build/tools/createDocument.js +15 -34
- package/build/tools/createTemplateFromDocument.js +7 -13
- package/build/tools/deleteComment.js +7 -13
- package/build/tools/deleteDocument.js +7 -13
- package/build/tools/getCollection.js +7 -13
- package/build/tools/getDocument.js +9 -13
- package/build/tools/listCollections.js +18 -12
- package/build/tools/listDocuments.js +34 -55
- package/build/tools/listUsers.js +31 -46
- package/build/tools/moveDocument.js +15 -21
- package/build/tools/searchDocuments.js +14 -21
- package/build/tools/updateCollection.js +14 -29
- package/build/tools/updateComment.js +9 -21
- package/build/tools/updateDocument.js +11 -29
- package/build/utils/getMcpServer.js +16 -0
- package/build/utils/{importTools.js → loadAllTools.js} +8 -5
- package/build/utils/toolRegistry.js +27 -0
- package/package.json +18 -21
- package/bin/cli.js +0 -57
- package/build/e2e/archiveDocument.spec.js +0 -7
- package/build/e2e/askDocuments.spec.js +0 -7
- package/build/e2e/createCollection.spec.js +0 -7
- package/build/e2e/createComment.spec.js +0 -7
- package/build/e2e/createDocument.spec.js +0 -7
- package/build/e2e/createTemplateFromDocument.spec.js +0 -7
- package/build/e2e/deleteComment.spec.js +0 -7
- package/build/e2e/deleteDocument.spec.js +0 -7
- package/build/e2e/getCollection.spec.js +0 -7
- package/build/e2e/getDocument.spec.js +0 -7
- package/build/e2e/listCollections.spec.js +0 -7
- package/build/e2e/listDocuments.spec.js +0 -7
- package/build/e2e/moveDocument.spec.js +0 -7
- package/build/e2e/searchDocuments.spec.js +0 -7
- package/build/e2e/setup.js +0 -33
- package/build/e2e/updateCollection.spec.js +0 -7
- package/build/e2e/updateComment.spec.js +0 -7
- package/build/e2e/updateDocument.spec.js +0 -7
- package/build/e2e/util/smokeTest.js +0 -88
- package/build/types.js +0 -1
- package/build/utils/listTools.js +0 -10
- /package/build/{client.js → outline/outlineClient.js} +0 -0
package/README.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
A Model Context Protocol (MCP) server that provides tools for interacting with [Outline](https://www.getoutline.com/)'s API, enabling AI agents to manage documents, collections, and other entities programmatically through the Outline knowledge base platform.
|
4
4
|
|
5
|
+
> **Upgrade Notice:**
|
6
|
+
|
7
|
+
- v5 has introduced several breaking changes:
|
8
|
+
- this server support for both `stdio` and `sse` transport interfaces. It now solely exposes a [Streamable HTTP endpoint](https://modelcontextprotocol.io/specification/draft/basic/transports#streamable-http) at the `/mcp` route. If you require sse/stdio, downgrade to v4
|
9
|
+
- the `--port` CLI flag has been migrated to an environment variable, `OUTLINE_MCP_PORT`
|
10
|
+
|
5
11
|
## Features
|
6
12
|
|
7
13
|
- **Document Management**
|
@@ -32,38 +38,31 @@ A Model Context Protocol (MCP) server that provides tools for interacting with [
|
|
32
38
|
- **User Management**
|
33
39
|
- ✅ List and filter users
|
34
40
|
|
35
|
-
> **Note:** The SSE server implementation uses [Supergateway](https://github.com/supercorp-ai/supergateway), which provides more reliable connectivity when used with Cursor's MCP integration.
|
36
|
-
|
37
41
|
## Quick Start
|
38
42
|
|
39
43
|
### Prerequisites
|
40
44
|
|
41
|
-
- Node.js (
|
42
|
-
-
|
45
|
+
- Node.js (v20 or higher)
|
46
|
+
- Outline account with API access
|
43
47
|
- Outline API key with appropriate permissions
|
48
|
+
- Note: if you need to use the AI-powered ask feature, you must enable the "AI Answers" feature in your Outline Workspace settings
|
44
49
|
|
45
50
|
### Installation
|
46
51
|
|
47
52
|
```bash
|
48
|
-
# Run directly with npx
|
49
|
-
OUTLINE_API_KEY
|
53
|
+
# (preferred) Run directly with npx
|
54
|
+
OUTLINE_API_KEY=... npx outline-mcp-server
|
50
55
|
|
51
56
|
# or install from npm
|
52
57
|
npm install -g outline-mcp-server
|
53
|
-
OUTLINE_API_KEY
|
54
|
-
|
55
|
-
# Run with a custom port (default is 6060)
|
56
|
-
OUTLINE_API_KEY=… outline-mcp-server --port 7070
|
58
|
+
OUTLINE_API_KEY=... outline-mcp-server
|
57
59
|
```
|
58
60
|
|
59
61
|
### Env
|
60
62
|
|
61
63
|
- `OUTLINE_API_KEY` (_required_): your API key for outline, duh
|
62
|
-
- `
|
63
|
-
|
64
|
-
### CLI Options
|
65
|
-
|
66
|
-
- `--port <number>` (_optional_): Specify the port on which the server will run (default: 6060)
|
64
|
+
- `OUTLINE_API_URL` (_optional_): Alternative URL for your outline API (if using an alt domain/self-hosting)
|
65
|
+
- `OUTLINE_MCP_PORT` (_optional_): Specify the port on which the server will run (default: 6060)
|
67
66
|
|
68
67
|
### Usage
|
69
68
|
|
@@ -79,6 +78,16 @@ Example queries your AI assistant can now handle:
|
|
79
78
|
- "Update the content of a document"
|
80
79
|
- "Add a comment to a document"
|
81
80
|
|
81
|
+
### Run the MCP server
|
82
|
+
|
83
|
+
```bash
|
84
|
+
# Default port 6060
|
85
|
+
OUTLINE_API_KEY=... npm run start:http
|
86
|
+
|
87
|
+
# Or specify a custom port
|
88
|
+
OUTLINE_API_KEY=... OUTLINE_MCP_PORT=9001 npm run start:http
|
89
|
+
```
|
90
|
+
|
82
91
|
## Development
|
83
92
|
|
84
93
|
```bash
|
@@ -94,13 +103,15 @@ npm install
|
|
94
103
|
|
95
104
|
```
|
96
105
|
OUTLINE_API_KEY=your_outline_api_key_here
|
97
|
-
|
106
|
+
|
107
|
+
# Optional -------
|
108
|
+
# OUTLINE_API_URL=https://your-outline-instance.com/api # defaults to https://app.getoutline.com/api
|
109
|
+
# OUTLINE_MCP_PORT=9001
|
98
110
|
```
|
99
111
|
|
100
112
|
```bash
|
101
113
|
# Builds/watches the project alongside running @modelcontextprotocol/inspector
|
102
114
|
npm run dev
|
103
|
-
|
104
115
|
```
|
105
116
|
|
106
117
|
## Contributing
|
package/build/index.js
CHANGED
@@ -1,58 +1,59 @@
|
|
1
|
-
|
2
|
-
import
|
3
|
-
import {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
// Dynamically import all tool files
|
8
|
-
const toolDefinitions = await registerTools();
|
9
|
-
console.log('\n', `loaded ${Object.keys(toolDefinitions).length} tools`, JSON.stringify(Object.keys(toolDefinitions)), '\n');
|
10
|
-
const server = new Server({
|
11
|
-
name: 'outline-mcp',
|
12
|
-
version: '1.0.0',
|
13
|
-
}, {
|
14
|
-
capabilities: {
|
15
|
-
tools: Object.entries(toolDefinitions).reduce((acc, [name, definition]) => {
|
16
|
-
acc[name] = true;
|
17
|
-
return acc;
|
18
|
-
}, {}),
|
19
|
-
},
|
20
|
-
});
|
21
|
-
// Register request handlers
|
22
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
23
|
-
tools: Object.values(toolDefinitions).map(x => omit(x, ['handler'])),
|
24
|
-
}));
|
25
|
-
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
26
|
-
const { params } = request;
|
27
|
-
const toolName = params.name;
|
28
|
-
const parameters = params.arguments || {};
|
29
|
-
const toolDefinition = toolDefinitions[toolName];
|
1
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
2
|
+
import fastify from 'fastify';
|
3
|
+
import { getMcpServer } from './utils/getMcpServer.js';
|
4
|
+
const server = fastify();
|
5
|
+
// Stateless mode (default, recommended for most deployments)
|
6
|
+
server.post('/mcp', async (request, reply) => {
|
30
7
|
try {
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
};
|
8
|
+
const mcpServer = await getMcpServer();
|
9
|
+
const httpTransport = new StreamableHTTPServerTransport({
|
10
|
+
sessionIdGenerator: undefined,
|
11
|
+
});
|
12
|
+
reply.raw.on('close', () => {
|
13
|
+
httpTransport.close();
|
14
|
+
mcpServer.close();
|
15
|
+
});
|
16
|
+
await mcpServer.connect(httpTransport);
|
17
|
+
await httpTransport.handleRequest(request.raw, reply.raw, request.body);
|
42
18
|
}
|
43
19
|
catch (error) {
|
44
|
-
if (
|
45
|
-
|
20
|
+
if (!reply.sent) {
|
21
|
+
reply.code(500).send({
|
22
|
+
jsonrpc: '2.0',
|
23
|
+
error: {
|
24
|
+
code: -32603,
|
25
|
+
message: 'Internal server error',
|
26
|
+
},
|
27
|
+
id: null,
|
28
|
+
});
|
46
29
|
}
|
47
|
-
return { error: { code: ErrorCode.InternalError, message: error.message } };
|
48
30
|
}
|
49
31
|
});
|
50
|
-
async
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
32
|
+
server.get('/mcp', async (request, reply) => {
|
33
|
+
reply.code(405).send({
|
34
|
+
jsonrpc: '2.0',
|
35
|
+
error: {
|
36
|
+
code: -32000,
|
37
|
+
message: 'Method not allowed.',
|
38
|
+
},
|
39
|
+
id: null,
|
40
|
+
});
|
41
|
+
});
|
42
|
+
server.delete('/mcp', async (request, reply) => {
|
43
|
+
reply.code(405).send({
|
44
|
+
jsonrpc: '2.0',
|
45
|
+
error: {
|
46
|
+
code: -32000,
|
47
|
+
message: 'Method not allowed.',
|
48
|
+
},
|
49
|
+
id: null,
|
50
|
+
});
|
51
|
+
});
|
52
|
+
const PORT = process.env.OUTLINE_MCP_PORT ? parseInt(process.env.OUTLINE_MCP_PORT, 10) : 6060;
|
53
|
+
server.listen({ port: PORT }, (err, address) => {
|
54
|
+
if (err) {
|
55
|
+
console.error(err);
|
56
|
+
process.exit(1);
|
57
|
+
}
|
58
|
+
console.log(`Outline MCP Server (streamable-http) running at ${address}/mcp`);
|
58
59
|
});
|
@@ -1,26 +1,20 @@
|
|
1
1
|
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
2
|
-
import { outlineClient } from '../
|
3
|
-
import
|
2
|
+
import { outlineClient } from '../outline/outlineClient.js';
|
3
|
+
import toolRegistry from '../utils/toolRegistry.js';
|
4
|
+
import { z } from 'zod';
|
4
5
|
// Register this tool
|
5
|
-
|
6
|
+
toolRegistry.register('archive-document', {
|
6
7
|
name: 'archive_document',
|
7
8
|
description: 'Archive a document',
|
8
9
|
inputSchema: {
|
9
|
-
|
10
|
-
id: {
|
11
|
-
type: 'string',
|
12
|
-
description: 'ID of the document to archive',
|
13
|
-
},
|
14
|
-
},
|
15
|
-
required: ['id'],
|
16
|
-
type: 'object',
|
10
|
+
id: z.string().describe('ID of the document to archive'),
|
17
11
|
},
|
18
|
-
|
12
|
+
async callback(args) {
|
19
13
|
try {
|
20
14
|
const response = await outlineClient.post('/documents.archive', {
|
21
15
|
id: args.id,
|
22
16
|
});
|
23
|
-
return response.data.data;
|
17
|
+
return { content: [{ type: 'text', text: JSON.stringify(response.data.data) }] };
|
24
18
|
}
|
25
19
|
catch (error) {
|
26
20
|
console.error('Error archiving document:', error.message);
|
@@ -1,43 +1,29 @@
|
|
1
1
|
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
2
|
-
import { outlineClient } from '../
|
3
|
-
import
|
2
|
+
import { outlineClient } from '../outline/outlineClient.js';
|
3
|
+
import toolRegistry from '../utils/toolRegistry.js';
|
4
|
+
import z from 'zod';
|
4
5
|
// Register this tool
|
5
|
-
|
6
|
+
toolRegistry.register('ask_documents', {
|
6
7
|
name: 'ask_documents',
|
7
8
|
description: 'Query documents with natural language. This method allows asking direct questions of your documents - where possible an answer will be provided. Search results will be restricted to those accessible by the current access token. Note that "AI answers" must be enabled for the workspace.',
|
8
9
|
inputSchema: {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
description: 'A document to search within',
|
25
|
-
},
|
26
|
-
statusFilter: {
|
27
|
-
type: 'string',
|
28
|
-
enum: ['draft', 'archived', 'published'],
|
29
|
-
description: 'Any documents that are not in the specified status will be filtered out',
|
30
|
-
},
|
31
|
-
dateFilter: {
|
32
|
-
type: 'string',
|
33
|
-
enum: ['day', 'week', 'month', 'year'],
|
34
|
-
description: 'Any documents that have not been updated within the specified period will be filtered out',
|
35
|
-
},
|
36
|
-
},
|
37
|
-
required: ['query'],
|
38
|
-
type: 'object',
|
10
|
+
query: z.string().describe('The natural language query to ask about your documents'),
|
11
|
+
userId: z
|
12
|
+
.string()
|
13
|
+
.describe('Any documents that have not been edited by the user identifier will be filtered out')
|
14
|
+
.optional(),
|
15
|
+
collectionId: z.string().describe('A collection to search within').optional(),
|
16
|
+
documentId: z.string().describe('A document to search within').optional(),
|
17
|
+
statusFilter: z
|
18
|
+
.enum(['draft', 'archived', 'published'])
|
19
|
+
.describe('Any documents that are not in the specified status will be filtered out')
|
20
|
+
.optional(),
|
21
|
+
dateFilter: z
|
22
|
+
.enum(['day', 'week', 'month', 'year'])
|
23
|
+
.describe('Any documents that have not been updated within the specified period will be filtered out')
|
24
|
+
.optional(),
|
39
25
|
},
|
40
|
-
|
26
|
+
async callback(args) {
|
41
27
|
try {
|
42
28
|
const payload = {
|
43
29
|
query: args.query,
|
@@ -58,7 +44,7 @@ registerTool({
|
|
58
44
|
payload.dateFilter = args.dateFilter;
|
59
45
|
}
|
60
46
|
const response = await outlineClient.post('/documents.answerQuestion', payload);
|
61
|
-
return response.data;
|
47
|
+
return { content: [{ type: 'text', text: JSON.stringify(response.data.data) }] };
|
62
48
|
}
|
63
49
|
catch (error) {
|
64
50
|
console.error('Error asking documents:', error.message);
|
@@ -1,37 +1,22 @@
|
|
1
1
|
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
2
|
-
import { outlineClient } from '../
|
3
|
-
import
|
2
|
+
import { outlineClient } from '../outline/outlineClient.js';
|
3
|
+
import toolRegistry from '../utils/toolRegistry.js';
|
4
|
+
import z from 'zod';
|
4
5
|
// Register this tool
|
5
|
-
|
6
|
+
toolRegistry.register('create_collection', {
|
6
7
|
name: 'create_collection',
|
7
8
|
description: 'Create a new collection',
|
8
9
|
inputSchema: {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
},
|
18
|
-
permission: {
|
19
|
-
type: 'string',
|
20
|
-
description: 'Permission level for the collection (read, read_write)',
|
21
|
-
},
|
22
|
-
color: {
|
23
|
-
type: 'string',
|
24
|
-
description: 'Hex color code for the collection',
|
25
|
-
},
|
26
|
-
private: {
|
27
|
-
type: 'boolean',
|
28
|
-
description: 'Whether this collection is private',
|
29
|
-
},
|
30
|
-
},
|
31
|
-
required: ['name'],
|
32
|
-
type: 'object',
|
10
|
+
name: z.string().describe('Title of the collection'),
|
11
|
+
description: z.string().describe('Content of the collection in markdown format').optional(),
|
12
|
+
permission: z
|
13
|
+
.enum(['read', 'read_write'])
|
14
|
+
.describe('Permission level for the collection')
|
15
|
+
.optional(),
|
16
|
+
color: z.string().describe('Hex color code for the collection').optional(),
|
17
|
+
private: z.boolean().describe('Whether this collection is private').optional(),
|
33
18
|
},
|
34
|
-
|
19
|
+
async callback(args) {
|
35
20
|
try {
|
36
21
|
const payload = {
|
37
22
|
name: args.name,
|
@@ -49,7 +34,7 @@ registerTool({
|
|
49
34
|
payload.private = args.private;
|
50
35
|
}
|
51
36
|
const response = await outlineClient.post('/collections.create', payload);
|
52
|
-
return response.data.data;
|
37
|
+
return { content: [{ type: 'text', text: JSON.stringify(response.data.data) }] };
|
53
38
|
}
|
54
39
|
catch (error) {
|
55
40
|
console.error('Error creating collection:', error.message);
|
@@ -1,33 +1,21 @@
|
|
1
1
|
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
2
|
-
import { outlineClient } from '../
|
3
|
-
import
|
2
|
+
import { outlineClient } from '../outline/outlineClient.js';
|
3
|
+
import toolRegistry from '../utils/toolRegistry.js';
|
4
|
+
import z from 'zod';
|
4
5
|
// Register this tool
|
5
|
-
|
6
|
+
toolRegistry.register('create_comment', {
|
6
7
|
name: 'create_comment',
|
7
8
|
description: 'Create a new comment on a document',
|
8
9
|
inputSchema: {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
description: 'Content of the comment in markdown format',
|
17
|
-
},
|
18
|
-
parentCommentId: {
|
19
|
-
type: 'string',
|
20
|
-
description: 'ID of the parent comment (if replying to a comment)',
|
21
|
-
},
|
22
|
-
data: {
|
23
|
-
type: 'object',
|
24
|
-
description: 'Additional data for the comment (optional)',
|
25
|
-
},
|
26
|
-
},
|
27
|
-
required: ['documentId', 'text'],
|
28
|
-
type: 'object',
|
10
|
+
documentId: z.string().describe('ID of the document to comment on'),
|
11
|
+
text: z.string().describe('Content of the comment in markdown format'),
|
12
|
+
parentCommentId: z
|
13
|
+
.string()
|
14
|
+
.describe('ID of the parent comment (if replying to a comment)')
|
15
|
+
.optional(),
|
16
|
+
data: z.object({}).describe('Additional data for the comment (optional)').optional(),
|
29
17
|
},
|
30
|
-
|
18
|
+
async callback(args) {
|
31
19
|
try {
|
32
20
|
const payload = {
|
33
21
|
documentId: args.documentId,
|
@@ -40,7 +28,7 @@ registerTool({
|
|
40
28
|
payload.data = args.data;
|
41
29
|
}
|
42
30
|
const response = await outlineClient.post('/comments.create', payload);
|
43
|
-
return response.data.data;
|
31
|
+
return { content: [{ type: 'text', text: JSON.stringify(response.data.data) }] };
|
44
32
|
}
|
45
33
|
catch (error) {
|
46
34
|
console.error('Error creating comment:', error.message);
|
@@ -1,42 +1,23 @@
|
|
1
1
|
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
2
|
-
import { outlineClient } from '../
|
3
|
-
import
|
2
|
+
import { outlineClient } from '../outline/outlineClient.js';
|
3
|
+
import toolRegistry from '../utils/toolRegistry.js';
|
4
|
+
import z from 'zod';
|
4
5
|
// Register this tool
|
5
|
-
|
6
|
+
toolRegistry.register('create_document', {
|
6
7
|
name: 'create_document',
|
7
8
|
description: 'Create a new document',
|
8
9
|
inputSchema: {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
collectionId: {
|
19
|
-
type: 'string',
|
20
|
-
description: 'ID of the collection to add the document to',
|
21
|
-
},
|
22
|
-
parentDocumentId: {
|
23
|
-
type: 'string',
|
24
|
-
description: 'ID of the parent document (if creating a nested document)',
|
25
|
-
},
|
26
|
-
publish: {
|
27
|
-
type: 'boolean',
|
28
|
-
default: true,
|
29
|
-
description: 'Whether to publish the document immediately',
|
30
|
-
},
|
31
|
-
template: {
|
32
|
-
type: 'boolean',
|
33
|
-
description: 'Whether this document is a template',
|
34
|
-
},
|
35
|
-
},
|
36
|
-
required: ['title', 'text', 'collectionId'],
|
37
|
-
type: 'object',
|
10
|
+
title: z.string().describe('Title of the document'),
|
11
|
+
text: z.string().describe('Content of the document in markdown format'),
|
12
|
+
collectionId: z.string().describe('ID of the collection to add the document to'),
|
13
|
+
parentDocumentId: z
|
14
|
+
.string()
|
15
|
+
.describe('ID of the parent document (if creating a nested document)')
|
16
|
+
.optional(),
|
17
|
+
publish: z.boolean().describe('Whether to publish the document immediately').optional(),
|
18
|
+
template: z.boolean().describe('Whether this document is a template').optional(),
|
38
19
|
},
|
39
|
-
|
20
|
+
async callback(args) {
|
40
21
|
try {
|
41
22
|
const payload = {
|
42
23
|
title: args.title,
|
@@ -53,7 +34,7 @@ registerTool({
|
|
53
34
|
payload.template = args.template;
|
54
35
|
}
|
55
36
|
const response = await outlineClient.post('/documents', payload);
|
56
|
-
return response.data.data;
|
37
|
+
return { content: [{ type: 'text', text: JSON.stringify(response.data.data) }] };
|
57
38
|
}
|
58
39
|
catch (error) {
|
59
40
|
console.error('Error creating document:', error.message);
|
@@ -1,27 +1,21 @@
|
|
1
1
|
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
2
|
-
import { outlineClient } from '../
|
3
|
-
import
|
2
|
+
import { outlineClient } from '../outline/outlineClient.js';
|
3
|
+
import toolRegistry from '../utils/toolRegistry.js';
|
4
|
+
import z from 'zod';
|
4
5
|
// Register this tool
|
5
|
-
|
6
|
+
toolRegistry.register('create_template_from_document', {
|
6
7
|
name: 'create_template_from_document',
|
7
8
|
description: 'Create a template from an existing document. This method allows you to create a new template using an existing document as the basis.',
|
8
9
|
inputSchema: {
|
9
|
-
|
10
|
-
id: {
|
11
|
-
type: 'string',
|
12
|
-
description: 'The ID of the document to use as a basis for the template',
|
13
|
-
},
|
14
|
-
},
|
15
|
-
required: ['id'],
|
16
|
-
type: 'object',
|
10
|
+
id: z.string().describe('The ID of the document to use as a basis for the template'),
|
17
11
|
},
|
18
|
-
|
12
|
+
async callback(args) {
|
19
13
|
try {
|
20
14
|
const payload = {
|
21
15
|
id: args.id,
|
22
16
|
};
|
23
17
|
const response = await outlineClient.post('/documents.templatize', payload);
|
24
|
-
return response.data.data;
|
18
|
+
return { content: [{ type: 'text', text: JSON.stringify(response.data.data) }] };
|
25
19
|
}
|
26
20
|
catch (error) {
|
27
21
|
console.error('Error creating template from document:', error.message);
|
@@ -1,26 +1,20 @@
|
|
1
1
|
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
2
|
-
import { outlineClient } from '../
|
3
|
-
import
|
2
|
+
import { outlineClient } from '../outline/outlineClient.js';
|
3
|
+
import toolRegistry from '../utils/toolRegistry.js';
|
4
|
+
import z from 'zod';
|
4
5
|
// Register this tool
|
5
|
-
|
6
|
+
toolRegistry.register('delete_comment', {
|
6
7
|
name: 'delete_comment',
|
7
8
|
description: 'Delete a comment from a document',
|
8
9
|
inputSchema: {
|
9
|
-
|
10
|
-
id: {
|
11
|
-
type: 'string',
|
12
|
-
description: 'ID of the comment to delete',
|
13
|
-
},
|
14
|
-
},
|
15
|
-
required: ['id'],
|
16
|
-
type: 'object',
|
10
|
+
id: z.string().describe('ID of the comment to delete'),
|
17
11
|
},
|
18
|
-
|
12
|
+
async callback(args) {
|
19
13
|
try {
|
20
14
|
const response = await outlineClient.post('/comments.delete', {
|
21
15
|
id: args.id,
|
22
16
|
});
|
23
|
-
return response.data.success;
|
17
|
+
return { content: [{ type: 'text', text: JSON.stringify(response.data.success) }] };
|
24
18
|
}
|
25
19
|
catch (error) {
|
26
20
|
console.error('Error deleting comment:', error.message);
|
@@ -1,26 +1,20 @@
|
|
1
1
|
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
2
|
-
import { outlineClient } from '../
|
3
|
-
import
|
2
|
+
import { outlineClient } from '../outline/outlineClient.js';
|
3
|
+
import toolRegistry from '../utils/toolRegistry.js';
|
4
|
+
import z from 'zod';
|
4
5
|
// Register this tool
|
5
|
-
|
6
|
+
toolRegistry.register('delete_document', {
|
6
7
|
name: 'delete_document',
|
7
8
|
description: 'Delete a document',
|
8
9
|
inputSchema: {
|
9
|
-
|
10
|
-
id: {
|
11
|
-
type: 'string',
|
12
|
-
description: 'ID of the document to delete',
|
13
|
-
},
|
14
|
-
},
|
15
|
-
required: ['id'],
|
16
|
-
type: 'object',
|
10
|
+
id: z.string().describe('ID of the document to delete'),
|
17
11
|
},
|
18
|
-
|
12
|
+
async callback(args) {
|
19
13
|
try {
|
20
14
|
const response = await outlineClient.post('/documents.delete', {
|
21
15
|
id: args.id,
|
22
16
|
});
|
23
|
-
return response.data.success;
|
17
|
+
return { content: [{ type: 'text', text: JSON.stringify(response.data.success) }] };
|
24
18
|
}
|
25
19
|
catch (error) {
|
26
20
|
console.error('Error deleting document:', error.message);
|
@@ -1,24 +1,18 @@
|
|
1
1
|
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
2
|
-
import { outlineClient } from '../
|
3
|
-
import
|
2
|
+
import { outlineClient } from '../outline/outlineClient.js';
|
3
|
+
import toolRegistry from '../utils/toolRegistry.js';
|
4
|
+
import z from 'zod';
|
4
5
|
// Register this tool
|
5
|
-
|
6
|
+
toolRegistry.register('get_collection', {
|
6
7
|
name: 'get_collection',
|
7
8
|
description: 'Get details about a specific collection',
|
8
9
|
inputSchema: {
|
9
|
-
|
10
|
-
id: {
|
11
|
-
type: 'string',
|
12
|
-
description: 'ID of the collection to retrieve',
|
13
|
-
},
|
14
|
-
},
|
15
|
-
required: ['id'],
|
16
|
-
type: 'object',
|
10
|
+
id: z.string().describe('ID of the collection to retrieve'),
|
17
11
|
},
|
18
|
-
|
12
|
+
async callback(args) {
|
19
13
|
try {
|
20
14
|
const response = await outlineClient.post(`/collections.info`, { id: args.id });
|
21
|
-
return response.data.data;
|
15
|
+
return { content: [{ type: 'text', text: JSON.stringify(response.data.data) }] };
|
22
16
|
}
|
23
17
|
catch (error) {
|
24
18
|
console.error('Error getting collection:', error.message);
|