@nimbus-dev/connectors 0.2.3 → 0.3.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.
Files changed (44) hide show
  1. package/connectors/apple/src/server.ts +5 -1
  2. package/connectors/aws/src/server.ts +5 -1
  3. package/connectors/azure/src/server.ts +5 -1
  4. package/connectors/bitbucket/src/server.ts +5 -1
  5. package/connectors/circleci/src/server.ts +5 -1
  6. package/connectors/confluence/src/server.ts +5 -1
  7. package/connectors/fastmail/src/server.ts +5 -1
  8. package/connectors/gcp/src/server.ts +5 -1
  9. package/connectors/github/src/server.ts +2 -0
  10. package/connectors/github-actions/src/server.ts +5 -1
  11. package/connectors/gitlab/src/server.ts +5 -1
  12. package/connectors/gmail/src/server.ts +5 -1
  13. package/connectors/google-drive/src/server.ts +5 -1
  14. package/connectors/iac/src/server.ts +5 -1
  15. package/connectors/iac/src/tools.ts +77 -20
  16. package/connectors/imap/src/server.ts +5 -1
  17. package/connectors/jenkins/src/server.ts +5 -1
  18. package/connectors/jira/src/server.ts +5 -1
  19. package/connectors/kubernetes/src/server.ts +5 -1
  20. package/connectors/linear/src/server.ts +5 -1
  21. package/connectors/notion/src/server.ts +5 -1
  22. package/connectors/obsidian/src/server.ts +5 -1
  23. package/connectors/onedrive/src/server.ts +5 -1
  24. package/connectors/outlook/src/server.ts +5 -1
  25. package/connectors/pagerduty/src/server.ts +5 -1
  26. package/connectors/protonmail/src/server.ts +5 -1
  27. package/connectors/readwise/nimbus.extension.json +9 -1
  28. package/connectors/readwise/src/book-mapping.ts +109 -0
  29. package/connectors/readwise/src/extension.ts +11 -0
  30. package/connectors/readwise/src/highlight-mapping.ts +88 -0
  31. package/connectors/readwise/src/readwise-base.ts +6 -0
  32. package/connectors/readwise/src/record-fields.ts +72 -0
  33. package/connectors/readwise/src/sync-tool.ts +56 -0
  34. package/connectors/readwise/src/sync.ts +348 -0
  35. package/connectors/readwise/src/tools.ts +2 -2
  36. package/connectors/slack/src/server.ts +5 -1
  37. package/connectors/teams/src/server.ts +5 -1
  38. package/package.json +2 -2
  39. package/shared/cli-json-kit.ts +1 -13
  40. package/shared/consent-kit.ts +39 -17
  41. package/shared/nimbus-spawn.ts +31 -1
  42. package/shared/run-read-only-mcp-connector.ts +7 -1
  43. package/shared/safe-cli-arg.ts +0 -20
  44. package/shared/windows-batch-args.ts +23 -9
@@ -12,6 +12,7 @@
12
12
 
13
13
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
14
14
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
15
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
15
16
  import { requireProcessEnv } from "../../../shared/mcp-tool-kit.ts";
16
17
  import {
17
18
  createAppleCalDavClient,
@@ -39,7 +40,10 @@ try {
39
40
  // non-fatal; listEvents/list tools will re-discover on demand
40
41
  }
41
42
 
42
- const server = new McpServer({ name: "nimbus-apple", version: "0.1.0" });
43
+ const server = new McpServer(
44
+ { name: "nimbus-apple", version: "0.1.0" },
45
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
46
+ );
43
47
 
44
48
  registerAppleTools(server, {
45
49
  client: createAppleImapClient(email, appPw),
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerAwsTools } from "./tools.ts";
4
5
 
5
- const mcp = new McpServer({ name: "nimbus-aws", version: "0.1.0" });
6
+ const mcp = new McpServer(
7
+ { name: "nimbus-aws", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerAwsTools(mcp);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerAzureTools } from "./tools.ts";
4
5
 
5
- const mcp = new McpServer({ name: "nimbus-azure", version: "0.1.0" });
6
+ const mcp = new McpServer(
7
+ { name: "nimbus-azure", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerAzureTools(mcp);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerBitbucketTools } from "./tools.ts";
4
5
 
5
- const server = new McpServer({ name: "nimbus-bitbucket", version: "0.1.0" });
6
+ const server = new McpServer(
7
+ { name: "nimbus-bitbucket", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerBitbucketTools(server);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerCircleciTools } from "./tools.ts";
4
5
 
5
- const mcp = new McpServer({ name: "nimbus-circleci", version: "0.1.0" });
6
+ const mcp = new McpServer(
7
+ { name: "nimbus-circleci", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerCircleciTools(mcp);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerConfluenceTools } from "./tools.ts";
4
5
 
5
- const server = new McpServer({ name: "nimbus-confluence", version: "0.1.0" });
6
+ const server = new McpServer(
7
+ { name: "nimbus-confluence", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerConfluenceTools(server);
8
12
 
@@ -1,9 +1,13 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { createFetchJmapClient } from "./jmap-client.ts";
4
5
  import { registerFastmailTools } from "./tools.ts";
5
6
 
6
- const server = new McpServer({ name: "nimbus-fastmail", version: "0.1.0" });
7
+ const server = new McpServer(
8
+ { name: "nimbus-fastmail", version: "0.1.0" },
9
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
10
+ );
7
11
  registerFastmailTools(server, createFetchJmapClient());
8
12
 
9
13
  await server.connect(new StdioServerTransport());
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerGcpTools } from "./tools.ts";
4
5
 
5
- const mcp = new McpServer({ name: "nimbus-gcp", version: "0.1.0" });
6
+ const mcp = new McpServer(
7
+ { name: "nimbus-gcp", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerGcpTools(mcp);
8
12
 
@@ -1,10 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerGithubTools } from "./tools.ts";
4
5
 
5
6
  const server = new McpServer(
6
7
  { name: "nimbus-github", version: "0.1.0" },
7
8
  {
9
+ capabilities: CONSENT_SERVER_CAPABILITIES,
8
10
  // Machine-readable security tiering, so a client can surface it rather than relying on a
9
11
  // human having read the NOTICE file.
10
12
  instructions:
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerGithubActionsTools } from "./tools.ts";
4
5
 
5
- const mcp = new McpServer({ name: "nimbus-github-actions", version: "0.1.0" });
6
+ const mcp = new McpServer(
7
+ { name: "nimbus-github-actions", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerGithubActionsTools(mcp);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerGitlabTools } from "./tools.ts";
4
5
 
5
- const server = new McpServer({ name: "nimbus-gitlab", version: "0.1.0" });
6
+ const server = new McpServer(
7
+ { name: "nimbus-gitlab", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerGitlabTools(server);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerGmailTools } from "./tools.ts";
4
5
 
5
- const server = new McpServer({ name: "nimbus-gmail", version: "0.1.0" });
6
+ const server = new McpServer(
7
+ { name: "nimbus-gmail", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerGmailTools(server);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerGoogleDriveTools } from "./tools.ts";
4
5
 
5
- const server = new McpServer({ name: "nimbus-google-drive", version: "0.1.0" });
6
+ const server = new McpServer(
7
+ { name: "nimbus-google-drive", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerGoogleDriveTools(server);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerIacTools } from "./tools.ts";
4
5
 
5
- const mcp = new McpServer({ name: "nimbus-iac", version: "0.1.0" });
6
+ const mcp = new McpServer(
7
+ { name: "nimbus-iac", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerIacTools(mcp);
8
12
 
@@ -1,5 +1,8 @@
1
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
1
4
  import { z } from "zod";
2
- import { awsCliArg, awsCliDocument, cliArg } from "../../../shared/cli-json-kit.ts";
5
+ import { awsCliArg, cliArg } from "../../../shared/cli-json-kit.ts";
3
6
  import type { ConsentServer } from "../../../shared/consent-kit.ts";
4
7
  import { createWriteToolRegistrar } from "../../../shared/consent-kit.ts";
5
8
  import {
@@ -9,6 +12,49 @@ import {
9
12
  } from "../../../shared/mcp-tool-kit.ts";
10
13
  import { runCliOkThrowing } from "../../../shared/run-cli-json.ts";
11
14
 
15
+ /**
16
+ * The most a template may be when it is deployed without an S3 bucket, which this tool does not
17
+ * take: `aws cloudformation deploy` refuses a larger one itself, and only after the prompt.
18
+ */
19
+ const TEMPLATE_MAX_BYTES = 51_200;
20
+
21
+ /**
22
+ * A CloudFormation template. It reaches the AWS CLI as a file, never as an argument (see
23
+ * {@link withTemplateFile}), so none of the argument rules apply to it: a YAML template may well
24
+ * start with `---`. Its size is refused here, in the schema, because no consent can lift it: a
25
+ * larger template would be put to the human, spend a unit of write budget, and then fail. The
26
+ * character bound is the one a client is shown; no string over it can be within the byte bound.
27
+ */
28
+ const templateDocument = z
29
+ .string()
30
+ .min(1)
31
+ .max(TEMPLATE_MAX_BYTES)
32
+ .refine((t) => new TextEncoder().encode(t).length <= TEMPLATE_MAX_BYTES, {
33
+ message: `must be at most ${String(TEMPLATE_MAX_BYTES)} bytes as UTF-8, the most aws cloudformation deploy takes without an S3 bucket`,
34
+ });
35
+
36
+ /**
37
+ * Run `body` with `template` written to a file of its own, removed afterwards however `body` ends.
38
+ *
39
+ * `aws cloudformation deploy` takes a template only as `--template-file`, and passing one as an
40
+ * argument would not work anyway: a template can run past the 32,767 characters a Windows command
41
+ * line holds, and an `aws` that is a batch file, as a pip-installed v1 is, has cmd.exe parse every
42
+ * quote in it.
43
+ */
44
+ async function withTemplateFile<T>(
45
+ template: string,
46
+ body: (path: string) => Promise<T>,
47
+ ): Promise<T> {
48
+ const dir = await mkdtemp(join(tmpdir(), "nimbus-cfn-"));
49
+ try {
50
+ const path = join(dir, "template");
51
+ await writeFile(path, template, { encoding: "utf8", mode: 0o600, flag: "wx" });
52
+ return await body(path);
53
+ } finally {
54
+ await rm(dir, { recursive: true, force: true });
55
+ }
56
+ }
57
+
12
58
  /** Tool names exposed by this connector — for contract/introspection tests. */
13
59
  export const IAC_TOOL_NAMES = [
14
60
  "iac_terraform_plan",
@@ -42,9 +88,12 @@ export function registerIacTools(
42
88
  "Run terraform plan in a directory.",
43
89
  z.object({ workingDirectory: cliArg }),
44
90
  async (p) => {
45
- await runCliOkThrowing(["terraform", "-chdir", p.workingDirectory, "plan", "-input=false"], {
46
- ...processEnv,
47
- });
91
+ await runCliOkThrowing(
92
+ ["terraform", `-chdir=${p.workingDirectory}`, "plan", "-input=false"],
93
+ {
94
+ ...processEnv,
95
+ },
96
+ );
48
97
  return jsonResult({ ok: true });
49
98
  },
50
99
  );
@@ -60,7 +109,7 @@ export function registerIacTools(
60
109
  z.object({ workingDirectory: cliArg }),
61
110
  async (p) => {
62
111
  await runCliOkThrowing(
63
- ["terraform", "-chdir", p.workingDirectory, "apply", "-auto-approve", "-input=false"],
112
+ ["terraform", `-chdir=${p.workingDirectory}`, "apply", "-auto-approve", "-input=false"],
64
113
  { ...processEnv },
65
114
  );
66
115
  return jsonResult({ ok: true });
@@ -82,7 +131,7 @@ export function registerIacTools(
82
131
  z.object({ workingDirectory: cliArg }),
83
132
  async (p) => {
84
133
  await runCliOkThrowing(
85
- ["terraform", "-chdir", p.workingDirectory, "destroy", "-auto-approve", "-input=false"],
134
+ ["terraform", `-chdir=${p.workingDirectory}`, "destroy", "-auto-approve", "-input=false"],
86
135
  { ...processEnv },
87
136
  );
88
137
  return jsonResult({ ok: true });
@@ -99,22 +148,30 @@ export function registerIacTools(
99
148
  "Deploy a CloudFormation stack via AWS CLI.",
100
149
  z.object({
101
150
  stackName: awsCliArg,
102
- templateBody: awsCliDocument,
151
+ templateBody: templateDocument,
103
152
  }),
104
153
  async (p) => {
105
- await runCliOkThrowing(
106
- [
107
- "aws",
108
- "cloudformation",
109
- "deploy",
110
- "--stack-name",
111
- p.stackName,
112
- "--template-body",
113
- p.templateBody,
114
- "--capabilities",
115
- "CAPABILITY_IAM",
116
- ],
117
- { ...processEnv },
154
+ await withTemplateFile(p.templateBody, (templateFile) =>
155
+ runCliOkThrowing(
156
+ [
157
+ "aws",
158
+ "cloudformation",
159
+ "deploy",
160
+ "--stack-name",
161
+ p.stackName,
162
+ "--template-file",
163
+ templateFile,
164
+ "--capabilities",
165
+ "CAPABILITY_IAM",
166
+ // A deploy of a template that changes nothing has done what was asked, not failed.
167
+ "--no-fail-on-empty-changeset",
168
+ ],
169
+ // The file is UTF-8. Left to itself the CLI reads it in the locale's encoding, and on a
170
+ // Windows machine using cp1252 a template holding "Á" fails to decode while one holding
171
+ // "é" deploys as "é". AWS CLI v2 reads AWS_CLI_FILE_ENCODING and ignores PYTHONUTF8; v1,
172
+ // plain Python, reads PYTHONUTF8 and ignores the other. Both are set.
173
+ { ...processEnv, AWS_CLI_FILE_ENCODING: "UTF-8", PYTHONUTF8: "1" },
174
+ ),
118
175
  );
119
176
  return jsonResult({ ok: true });
120
177
  },
@@ -10,6 +10,7 @@
10
10
 
11
11
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
12
12
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
13
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
13
14
  import { envInt } from "../../../shared/imap-tool-kit.ts";
14
15
  import { createImapFlowClient, createNodemailerMailer } from "../../../shared/imapflow-adapter.ts";
15
16
  import { requireProcessEnv } from "../../../shared/mcp-tool-kit.ts";
@@ -22,7 +23,10 @@ const SMTPS_PORT = 465;
22
23
 
23
24
  const smtpPort = envInt("IMAP_SMTP_PORT", DEFAULT_SMTP_PORT);
24
25
 
25
- const server = new McpServer({ name: "nimbus-imap", version: "0.1.0" });
26
+ const server = new McpServer(
27
+ { name: "nimbus-imap", version: "0.1.0" },
28
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
29
+ );
26
30
 
27
31
  registerImapTools(
28
32
  server,
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerJenkinsTools } from "./tools.ts";
4
5
 
5
- const mcp = new McpServer({ name: "nimbus-jenkins", version: "0.1.0" });
6
+ const mcp = new McpServer(
7
+ { name: "nimbus-jenkins", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerJenkinsTools(mcp);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerJiraTools } from "./tools.ts";
4
5
 
5
- const server = new McpServer({ name: "nimbus-jira", version: "0.1.0" });
6
+ const server = new McpServer(
7
+ { name: "nimbus-jira", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerJiraTools(server);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerKubernetesTools } from "./tools.ts";
4
5
 
5
- const mcp = new McpServer({ name: "nimbus-kubernetes", version: "0.1.0" });
6
+ const mcp = new McpServer(
7
+ { name: "nimbus-kubernetes", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerKubernetesTools(mcp);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerLinearTools } from "./tools.ts";
4
5
 
5
- const server = new McpServer({ name: "nimbus-linear", version: "0.1.0" });
6
+ const server = new McpServer(
7
+ { name: "nimbus-linear", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerLinearTools(server);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerNotionTools } from "./tools.ts";
4
5
 
5
- const server = new McpServer({ name: "nimbus-notion", version: "0.1.0" });
6
+ const server = new McpServer(
7
+ { name: "nimbus-notion", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerNotionTools(server);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerObsidianTools } from "./tools.ts";
4
5
 
5
- const server = new McpServer({ name: "nimbus-obsidian", version: "0.1.0" });
6
+ const server = new McpServer(
7
+ { name: "nimbus-obsidian", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerObsidianTools(server);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerOnedriveTools } from "./tools.ts";
4
5
 
5
- const server = new McpServer({ name: "nimbus-onedrive", version: "0.1.0" });
6
+ const server = new McpServer(
7
+ { name: "nimbus-onedrive", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerOnedriveTools(server);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerOutlookTools } from "./tools.ts";
4
5
 
5
- const server = new McpServer({ name: "nimbus-outlook", version: "0.1.0" });
6
+ const server = new McpServer(
7
+ { name: "nimbus-outlook", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerOutlookTools(server);
8
12
 
@@ -1,8 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
3
4
  import { registerPagerdutyTools } from "./tools.ts";
4
5
 
5
- const mcp = new McpServer({ name: "nimbus-pagerduty", version: "0.1.0" });
6
+ const mcp = new McpServer(
7
+ { name: "nimbus-pagerduty", version: "0.1.0" },
8
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
9
+ );
6
10
 
7
11
  registerPagerdutyTools(mcp);
8
12
 
@@ -9,6 +9,7 @@
9
9
 
10
10
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
11
11
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
12
+ import { CONSENT_SERVER_CAPABILITIES } from "../../../shared/consent-kit.ts";
12
13
  import { optionalEnv } from "../../../shared/env-json-api.ts";
13
14
  import { envInt } from "../../../shared/imap-tool-kit.ts";
14
15
  import { createImapFlowClient, createNodemailerMailer } from "../../../shared/imapflow-adapter.ts";
@@ -28,7 +29,10 @@ const DEFAULT_SMTP_PORT = 1025;
28
29
  */
29
30
  const BRIDGE_TLS = { secure: false, rejectUnauthorized: false } as const;
30
31
 
31
- const server = new McpServer({ name: "nimbus-protonmail", version: "0.1.0" });
32
+ const server = new McpServer(
33
+ { name: "nimbus-protonmail", version: "0.1.0" },
34
+ { capabilities: CONSENT_SERVER_CAPABILITIES },
35
+ );
32
36
 
33
37
  registerProtonmailTools(
34
38
  server,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "com.nimbus.readwise",
3
3
  "displayName": "Readwise",
4
- "version": "0.1.0",
4
+ "version": "0.2.0",
5
5
  "description": "Readwise connector (read-only). Surfaces the user's saved book/article highlights as `readwise:highlight` items in the local index — the highlighted excerpt text, the user's note, the parent book/article id, the location + location type, the color, tags, and the source article URL (for web highlights) — plus their parent books/articles as `readwise:book` items (title, author, category, source, highlight count, document note, tags, ASIN, source + Readwise book-review URLs), so a highlight's `book_id` resolves to a real indexed record. Useful for answering reading questions (\"what did I highlight about retries?\", \"which book was that note in?\") without leaving Nimbus. Token API-token auth (`Authorization: Token <token>` — Django-REST-Framework token auth, NOT Bearer). The SaaS host (readwise.io) is fixed. Readwise paginates both `/api/v2/highlights/` and `/api/v2/books/` by page number (DRF `{ count, next, previous, results }` envelope, page_size=1000). `highlighted_at` / `last_highlight_at` / `updated` are ISO-8601 (converted to epoch-ms on index). Book `external_id`s are namespaced `book/<id>` because Readwise numbers books and highlights in separate sequences. Documents / daily-review and the Reader v3 API remain deferred follow-ups.",
6
6
  "author": "Nimbus",
7
7
  "entrypoint": "dist/server.js",
@@ -11,5 +11,13 @@
11
11
  },
12
12
  "hitlRequired": [],
13
13
  "syncInterval": 600,
14
+ "sync": {
15
+ "contract": "1",
16
+ "intervalSeconds": 600,
17
+ "itemTypes": ["highlight", "book"]
18
+ },
19
+ "credentials": {
20
+ "token": { "env": "READWISE_TOKEN" }
21
+ },
14
22
  "minNimbusVersion": "0.2.0"
15
23
  }