@docrouter/mcp 0.2.1 → 0.2.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/dist/index.mjs CHANGED
@@ -3,8 +3,8 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
4
  import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
5
5
  import { z } from 'zod';
6
- import { DocRouterOrg } from '@docrouter/sdk';
7
- import { readFileSync } from 'fs';
6
+ import { DocRouterAccount, DocRouterOrg } from '@docrouter/sdk';
7
+ import { readFileSync, existsSync } from 'fs';
8
8
  import { dirname, join } from 'path';
9
9
  import { fileURLToPath } from 'url';
10
10
 
@@ -16,11 +16,36 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
16
16
  });
17
17
  var ConfigSchema = z.object({
18
18
  baseURL: z.string().default("https://app.docrouter.ai/fastapi"),
19
- organizationId: z.string(),
20
19
  orgToken: z.string(),
21
20
  timeout: z.number().default(3e4),
22
21
  retries: z.number().default(3)
23
22
  });
23
+ function resolveKnowledgeBasePath(filename) {
24
+ const currentFile = fileURLToPath(import.meta.url);
25
+ const currentDir = dirname(currentFile);
26
+ if (currentDir.endsWith("dist")) {
27
+ return join(currentDir, "docs/knowledge_base", filename);
28
+ }
29
+ if (currentDir.endsWith("src")) {
30
+ const distPath = join(currentDir, "..", "dist", "docs/knowledge_base", filename);
31
+ if (existsSync(distPath)) {
32
+ return distPath;
33
+ }
34
+ throw new Error(
35
+ `Knowledge base file not found: ${filename}
36
+ Expected at: ${distPath}
37
+ Please run 'npm run build' first to generate the knowledge base files.`
38
+ );
39
+ }
40
+ const fallbackPath = join(currentDir, "docs/knowledge_base", filename);
41
+ if (existsSync(fallbackPath)) {
42
+ return fallbackPath;
43
+ }
44
+ throw new Error(
45
+ `Knowledge base file not found: ${filename}
46
+ Searched in: ${join(currentDir, "docs/knowledge_base", filename)}`
47
+ );
48
+ }
24
49
  function showTools() {
25
50
  const toolNames = tools.map((tool) => tool.name).sort();
26
51
  console.log(toolNames.join("\n"));
@@ -51,8 +76,7 @@ DESCRIPTION:
51
76
  OPTIONS:
52
77
  --url <URL> DocRouter API base URL
53
78
  (default: https://app.docrouter.ai/fastapi)
54
- --org-id <ID> DocRouter organization ID
55
- --org-token <TOKEN> DocRouter organization API token
79
+ --org-token <TOKEN> DocRouter organization API token (required)
56
80
  --timeout <MS> Request timeout in milliseconds (default: 30000)
57
81
  --retries <COUNT> Number of retry attempts (default: 3)
58
82
  --tools List all supported MCP tools
@@ -61,24 +85,22 @@ OPTIONS:
61
85
 
62
86
  ENVIRONMENT VARIABLES:
63
87
  DOCROUTER_API_URL DocRouter API base URL
64
- DOCROUTER_ORG_ID DocRouter organization ID
65
- DOCROUTER_ORG_API_TOKEN DocRouter organization API token
88
+ DOCROUTER_ORG_API_TOKEN DocRouter organization API token (required)
66
89
 
67
90
  EXAMPLES:
68
- # Using command line arguments
69
- docrouter-mcp --org-id "org123" --org-token "token456"
91
+ # Using command line arguments (organization ID will be resolved from token)
92
+ docrouter-mcp --org-token "token456"
70
93
 
71
- # Using environment variables
72
- export DOCROUTER_ORG_ID="org123"
94
+ # Using environment variables (organization ID will be resolved from token)
73
95
  export DOCROUTER_ORG_API_TOKEN="token456"
74
96
  docrouter-mcp
75
97
 
76
98
  # With custom API URL
77
- docrouter-mcp --url "https://custom.docrouter.ai/fastapi" --org-id "org123" --org-token "token456"
99
+ docrouter-mcp --url "https://custom.docrouter.ai/fastapi" --org-token "token456"
78
100
 
79
101
  REQUIRED:
80
- Either provide --org-id and --org-token as command line arguments,
81
- or set DOCROUTER_ORG_ID and DOCROUTER_ORG_API_TOKEN environment variables.
102
+ DOCROUTER_ORG_API_TOKEN environment variable or --org-token argument.
103
+ Organization ID will be automatically resolved from the token.
82
104
 
83
105
  For more information about DocRouter, visit: https://docrouter.ai
84
106
  `);
@@ -106,9 +128,6 @@ function parseConfig() {
106
128
  case "url":
107
129
  config.baseURL = value;
108
130
  break;
109
- case "org-id":
110
- config.organizationId = value;
111
- break;
112
131
  case "org-token":
113
132
  config.orgToken = value;
114
133
  break;
@@ -122,7 +141,6 @@ function parseConfig() {
122
141
  }
123
142
  }
124
143
  config.baseURL = config.baseURL || process.env.DOCROUTER_API_URL || "https://app.docrouter.ai/fastapi";
125
- config.organizationId = config.organizationId || process.env.DOCROUTER_ORG_ID || "";
126
144
  config.orgToken = config.orgToken || process.env.DOCROUTER_ORG_API_TOKEN || "";
127
145
  return ConfigSchema.parse(config);
128
146
  }
@@ -138,20 +156,57 @@ var server = new Server(
138
156
  }
139
157
  );
140
158
  var docrouterClient;
141
- function initializeClient(config) {
142
- docrouterClient = new DocRouterOrg({
143
- baseURL: config.baseURL,
144
- orgToken: config.orgToken,
145
- organizationId: config.organizationId,
146
- timeout: config.timeout,
147
- retries: config.retries
148
- });
159
+ async function initializeClient(config) {
160
+ try {
161
+ console.error("Resolving organization ID from token...");
162
+ const accountClient = new DocRouterAccount({
163
+ baseURL: config.baseURL,
164
+ accountToken: config.orgToken,
165
+ timeout: config.timeout,
166
+ retries: config.retries
167
+ });
168
+ const tokenResponse = await accountClient.getOrganizationFromToken(config.orgToken);
169
+ const organizationId = tokenResponse.organization_id;
170
+ if (!organizationId) {
171
+ throw new Error("Token is an account-level token, not an organization-specific token. Please use an organization API token.");
172
+ }
173
+ console.error(`Resolved organization ID: ${organizationId}`);
174
+ docrouterClient = new DocRouterOrg({
175
+ baseURL: config.baseURL,
176
+ orgToken: config.orgToken,
177
+ organizationId,
178
+ timeout: config.timeout,
179
+ retries: config.retries
180
+ });
181
+ } catch (error) {
182
+ throw new Error(`Failed to resolve organization ID from token: ${error instanceof Error ? error.message : "Unknown error"}`);
183
+ }
149
184
  }
150
185
  function handleError(error) {
151
186
  if (error instanceof Error) {
152
- return JSON.stringify({ error: error.message }, null, 2);
187
+ const apiError = error;
188
+ const errorObj = {
189
+ error: error.message
190
+ };
191
+ if (apiError.status !== void 0) {
192
+ errorObj.status = apiError.status;
193
+ }
194
+ if (apiError.code !== void 0) {
195
+ errorObj.code = apiError.code;
196
+ }
197
+ if (apiError.details !== void 0) {
198
+ errorObj.details = apiError.details;
199
+ }
200
+ return JSON.stringify(errorObj, null, 2);
153
201
  }
154
- return JSON.stringify({ error: "Unknown error occurred" }, null, 2);
202
+ if (typeof error === "object" && error !== null) {
203
+ try {
204
+ return JSON.stringify({ error: "Request failed", details: error }, null, 2);
205
+ } catch {
206
+ return JSON.stringify({ error: "Unknown error occurred (could not serialize)" }, null, 2);
207
+ }
208
+ }
209
+ return JSON.stringify({ error: String(error) || "Unknown error occurred" }, null, 2);
155
210
  }
156
211
  function serializeDates(obj) {
157
212
  if (obj === null || obj === void 0) {
@@ -887,9 +942,9 @@ var tools = [
887
942
  type: "object",
888
943
  properties: {
889
944
  promptId: { type: "string", description: "ID of the prompt" },
890
- prompt: { type: "object", description: "Prompt data" }
945
+ content: { type: "string", description: "Prompt content" }
891
946
  },
892
- required: ["promptId", "prompt"]
947
+ required: ["promptId", "content"]
893
948
  }
894
949
  },
895
950
  {
@@ -1475,9 +1530,29 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1475
1530
  };
1476
1531
  }
1477
1532
  case "update_prompt": {
1533
+ const promptId = getArg(args, "promptId");
1534
+ const content = getArg(args, "content");
1535
+ let currentPrompt = null;
1536
+ const allPrompts = await docrouterClient.listPrompts({});
1537
+ for (const p of allPrompts.prompts) {
1538
+ if (p.prompt_id === promptId) {
1539
+ currentPrompt = p;
1540
+ break;
1541
+ }
1542
+ }
1543
+ if (!currentPrompt) {
1544
+ throw new Error(`Prompt with ID ${promptId} not found`);
1545
+ }
1478
1546
  const result = await docrouterClient.updatePrompt({
1479
- promptId: getArg(args, "promptId"),
1480
- prompt: getArg(args, "prompt")
1547
+ promptId,
1548
+ prompt: {
1549
+ name: currentPrompt.name,
1550
+ content,
1551
+ schema_id: currentPrompt.schema_id,
1552
+ schema_version: currentPrompt.schema_version,
1553
+ tag_ids: currentPrompt.tag_ids,
1554
+ model: currentPrompt.model
1555
+ }
1481
1556
  });
1482
1557
  return {
1483
1558
  content: [
@@ -1768,9 +1843,7 @@ This server provides access to DocRouter resources and tools.
1768
1843
  }
1769
1844
  case "help_prompts": {
1770
1845
  try {
1771
- const currentFile = fileURLToPath(import.meta.url);
1772
- const currentDir = dirname(currentFile);
1773
- const promptsPath = join(currentDir, "docs/knowledge_base/prompts.md");
1846
+ const promptsPath = resolveKnowledgeBasePath("prompts.md");
1774
1847
  const promptsContent = readFileSync(promptsPath, "utf-8");
1775
1848
  return {
1776
1849
  content: [
@@ -1794,9 +1867,7 @@ This server provides access to DocRouter resources and tools.
1794
1867
  }
1795
1868
  case "help_schemas": {
1796
1869
  try {
1797
- const currentFile = fileURLToPath(import.meta.url);
1798
- const currentDir = dirname(currentFile);
1799
- const schemasPath = join(currentDir, "docs/knowledge_base/schemas.md");
1870
+ const schemasPath = resolveKnowledgeBasePath("schemas.md");
1800
1871
  const schemasContent = readFileSync(schemasPath, "utf-8");
1801
1872
  return {
1802
1873
  content: [
@@ -1820,9 +1891,7 @@ This server provides access to DocRouter resources and tools.
1820
1891
  }
1821
1892
  case "help_forms": {
1822
1893
  try {
1823
- const currentFile = fileURLToPath(import.meta.url);
1824
- const currentDir = dirname(currentFile);
1825
- const formsPath = join(currentDir, "docs/knowledge_base/forms.md");
1894
+ const formsPath = resolveKnowledgeBasePath("forms.md");
1826
1895
  const formsContent = readFileSync(formsPath, "utf-8");
1827
1896
  return {
1828
1897
  content: [
@@ -1862,12 +1931,13 @@ This server provides access to DocRouter resources and tools.
1862
1931
  async function main() {
1863
1932
  try {
1864
1933
  const config = parseConfig();
1865
- if (!config.organizationId || !config.orgToken) {
1866
- console.error("Error: DOCROUTER_ORG_ID and DOCROUTER_ORG_API_TOKEN environment variables are required");
1867
- console.error("Or provide them as command line arguments: --org-id <id> --org-token <token>");
1934
+ if (!config.orgToken) {
1935
+ console.error("Error: DOCROUTER_ORG_API_TOKEN environment variable is required");
1936
+ console.error("Or provide it as command line argument: --org-token <token>");
1937
+ console.error("Organization ID will be automatically resolved from the token.");
1868
1938
  process.exit(1);
1869
1939
  }
1870
- initializeClient(config);
1940
+ await initializeClient(config);
1871
1941
  const transport = new StdioServerTransport();
1872
1942
  await server.connect(transport);
1873
1943
  console.error("DocRouter MCP server started successfully");