initial-commit #1

Merged
t.behrendt merged 33 commits from initial-commit into main 2025-07-16 07:21:14 +02:00
4 changed files with 26 additions and 70 deletions
Showing only changes of commit d249cb4ae9 - Show all commits

View File

@@ -8,10 +8,19 @@ import tsPlugin from "typescript-eslint";
/** @type {import('eslint').Linter.Config[]} */ /** @type {import('eslint').Linter.Config[]} */
export default [ export default [
{
ignores: [
"node_modules/**",
"dist/**",
"build/**",
"coverage/**",
"*.min.js",
"src/gen/**", // Exclude generated API files
],
},
securityPlugin.configs.recommended, securityPlugin.configs.recommended,
{ {
files: ["**/*.ts"], files: ["src/**/*.ts"],
ignores: ["src/gen/**"],
}, },
{ {
languageOptions: { globals: globals.node }, languageOptions: { globals: globals.node },
@@ -60,16 +69,7 @@ export default [
"import/order": [ "import/order": [
"error", "error",
{ {
groups: [ groups: ["builtin", "external", "internal", "parent", "sibling", "index", "object", "type"],
"builtin",
"external",
"internal",
"parent",
"sibling",
"index",
"object",
"type",
],
"newlines-between": "always", "newlines-between": "always",
alphabetize: { alphabetize: {
order: "asc", order: "asc",

View File

@@ -7,11 +7,7 @@ import { registerDocumentTools } from "./tools/document";
import type { Logger } from "pino"; import type { Logger } from "pino";
const createOutlineClient = ( const createOutlineClient = (baseUrl: string, apiKey: string, logger: Logger) => {
baseUrl: string,
apiKey: string,
logger: Logger
) => {
const config = new Configuration({ const config = new Configuration({
basePath: baseUrl, basePath: baseUrl,
accessToken: () => Promise.resolve(apiKey), accessToken: () => Promise.resolve(apiKey),

View File

@@ -6,11 +6,7 @@ import type { ToolsFactory } from "./toolsFactory";
import type { CollectionsApi } from "../gen/api/outline"; import type { CollectionsApi } from "../gen/api/outline";
import type { Logger } from "pino"; import type { Logger } from "pino";
export const registerCollectionTools: ToolsFactory<CollectionsApi> = ( export const registerCollectionTools: ToolsFactory<CollectionsApi> = (server: McpServer, client: CollectionsApi, logger: Logger) => {
server: McpServer,
client: CollectionsApi,
logger: Logger
) => {
server.registerTool( server.registerTool(
"collections_list", "collections_list",
{ {
@@ -21,15 +17,9 @@ export const registerCollectionTools: ToolsFactory<CollectionsApi> = (
async () => { async () => {
try { try {
const response = await client.collectionsList(); const response = await client.collectionsList();
return handleSuccess( return handleSuccess(response, logger.child({ tool: "collections_list" }));
response,
logger.child({ tool: "collections_list" })
);
} catch (err) { } catch (err) {
const error = handleError( const error = handleError(err, logger.child({ tool: "collections_list" }));
err,
logger.child({ tool: "collections_list" })
);
logger.error(error); logger.error(error);
return error; return error;
} }

View File

@@ -1,45 +1,22 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod"; import { z } from "zod";
import type { Logger } from "pino";
import { import { backlinkDocumentId, collectionId, direction, limit, offset, parentDocumentId, sort, userId } from "./common";
backlinkDocumentId,
collectionId,
direction,
limit,
offset,
parentDocumentId,
sort,
userId,
} from "./common";
import { handleSuccess, handleError } from "./utils"; import { handleSuccess, handleError } from "./utils";
import type { ToolsFactory } from "./toolsFactory"; import type { ToolsFactory } from "./toolsFactory";
import type { DocumentsApi } from "../gen/api/outline"; import type { DocumentsApi } from "../gen/api/outline";
import type { Logger } from "pino";
export const registerDocumentTools: ToolsFactory<DocumentsApi> = ( export const registerDocumentTools: ToolsFactory<DocumentsApi> = (server: McpServer, client: DocumentsApi, logger: Logger): void => {
server: McpServer,
client: DocumentsApi,
logger: Logger
): void => {
server.registerTool( server.registerTool(
"documents_info", "documents_info",
{ {
title: "Get Document Info", title: "Get Document Info",
description: description: "Retrieve a document by its UUID, urlId, or shareId. At least one of these parameters must be provided.",
"Retrieve a document by its UUID, urlId, or shareId. At least one of these parameters must be provided.",
inputSchema: { inputSchema: {
id: z id: z.string().optional().describe("Unique identifier for the document. Either the UUID or the urlId is acceptable."),
.string() shareId: z.string().optional().describe("Unique identifier for a document share, a shareId may be used in place of a document UUID"),
.optional()
.describe(
"Unique identifier for the document. Either the UUID or the urlId is acceptable."
),
shareId: z
.string()
.optional()
.describe(
"Unique identifier for a document share, a shareId may be used in place of a document UUID"
),
}, },
}, },
async (args) => { async (args) => {
@@ -50,10 +27,7 @@ export const registerDocumentTools: ToolsFactory<DocumentsApi> = (
shareId: args?.shareId, shareId: args?.shareId,
}, },
}); });
return handleSuccess( return handleSuccess(response, logger.child({ tool: "documents_info" }));
response,
logger.child({ tool: "documents_info" })
);
} catch (error) { } catch (error) {
return handleError(error, logger.child({ tool: "documents_info" })); return handleError(error, logger.child({ tool: "documents_info" }));
} }
@@ -76,8 +50,7 @@ export const registerDocumentTools: ToolsFactory<DocumentsApi> = (
"documents_list", "documents_list",
{ {
title: "List Documents", title: "List Documents",
description: description: "This method will list all published documents and draft documents belonging to the current user.",
"This method will list all published documents and draft documents belonging to the current user.",
inputSchema: documentsListSchema.shape, inputSchema: documentsListSchema.shape,
}, },
async (args) => { async (args) => {
@@ -86,10 +59,7 @@ export const registerDocumentTools: ToolsFactory<DocumentsApi> = (
const response = await client.documentsList({ const response = await client.documentsList({
documentsListRequest: validatedArgs, documentsListRequest: validatedArgs,
}); });
return handleSuccess( return handleSuccess(response, logger.child({ tool: "documents_list" }));
response,
logger.child({ tool: "documents_list" })
);
} catch (error) { } catch (error) {
return handleError(error, logger.child({ tool: "documents_list" })); return handleError(error, logger.child({ tool: "documents_list" }));
} }