@nimbus-dev/connectors 0.1.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/LICENSE +662 -0
- package/NOTICE +40 -0
- package/README.md +111 -0
- package/connectors/airflow/nimbus.extension.json +16 -0
- package/connectors/airflow/src/search-filter.ts +38 -0
- package/connectors/airflow/src/server.ts +91 -0
- package/connectors/apple/nimbus.extension.json +40 -0
- package/connectors/apple/src/apple-mail-core.ts +43 -0
- package/connectors/apple/src/caldav-core.ts +116 -0
- package/connectors/apple/src/calendar-tools.ts +278 -0
- package/connectors/apple/src/server.ts +541 -0
- package/connectors/apple/src/tools.ts +138 -0
- package/connectors/argocd/nimbus.extension.json +16 -0
- package/connectors/argocd/src/search-filter.ts +24 -0
- package/connectors/argocd/src/server.ts +158 -0
- package/connectors/athena/nimbus.extension.json +15 -0
- package/connectors/athena/src/server.ts +6 -0
- package/connectors/athena/src/tools.ts +181 -0
- package/connectors/aws/nimbus.extension.json +21 -0
- package/connectors/aws/src/server.ts +191 -0
- package/connectors/azure/nimbus.extension.json +15 -0
- package/connectors/azure/src/server.ts +139 -0
- package/connectors/bigeye/nimbus.extension.json +16 -0
- package/connectors/bigeye/src/search-filter.ts +22 -0
- package/connectors/bigeye/src/server.ts +161 -0
- package/connectors/bigquery/nimbus.extension.json +15 -0
- package/connectors/bigquery/src/server.ts +6 -0
- package/connectors/bigquery/src/tools.ts +175 -0
- package/connectors/bitbucket/nimbus.extension.json +15 -0
- package/connectors/bitbucket/src/server.ts +252 -0
- package/connectors/bitrise/nimbus.extension.json +15 -0
- package/connectors/bitrise/src/search-filter.ts +11 -0
- package/connectors/bitrise/src/server.ts +83 -0
- package/connectors/canva/nimbus.extension.json +15 -0
- package/connectors/canva/src/search-filter.ts +23 -0
- package/connectors/canva/src/server.ts +77 -0
- package/connectors/circleci/nimbus.extension.json +15 -0
- package/connectors/circleci/src/server.ts +184 -0
- package/connectors/cloud-logging/nimbus.extension.json +15 -0
- package/connectors/cloud-logging/src/server.ts +6 -0
- package/connectors/cloud-logging/src/tools.ts +115 -0
- package/connectors/cloudwatch/nimbus.extension.json +15 -0
- package/connectors/cloudwatch/src/server.ts +6 -0
- package/connectors/cloudwatch/src/tools.ts +144 -0
- package/connectors/codemagic/nimbus.extension.json +15 -0
- package/connectors/codemagic/src/search-filter.ts +11 -0
- package/connectors/codemagic/src/server.ts +74 -0
- package/connectors/confluence/nimbus.extension.json +15 -0
- package/connectors/confluence/src/kb-append.ts +25 -0
- package/connectors/confluence/src/server.ts +309 -0
- package/connectors/dagster/nimbus.extension.json +16 -0
- package/connectors/dagster/src/search-filter.ts +53 -0
- package/connectors/dagster/src/server.ts +218 -0
- package/connectors/databricks/nimbus.extension.json +16 -0
- package/connectors/databricks/src/search-filter.ts +28 -0
- package/connectors/databricks/src/server.ts +81 -0
- package/connectors/datadog/nimbus.extension.json +15 -0
- package/connectors/datadog/src/server.ts +56 -0
- package/connectors/dataprofile/nimbus.extension.json +16 -0
- package/connectors/dataprofile/src/profile.ts +298 -0
- package/connectors/dataprofile/src/server.ts +6 -0
- package/connectors/dataprofile/src/tools.ts +69 -0
- package/connectors/dbt/nimbus.extension.json +16 -0
- package/connectors/dbt/src/search-filter.ts +28 -0
- package/connectors/dbt/src/server.ts +96 -0
- package/connectors/dependencytrack/nimbus.extension.json +16 -0
- package/connectors/dependencytrack/src/search-filter.ts +24 -0
- package/connectors/dependencytrack/src/server.ts +80 -0
- package/connectors/discord/nimbus.extension.json +15 -0
- package/connectors/discord/src/server.ts +93 -0
- package/connectors/elasticsearch/nimbus.extension.json +16 -0
- package/connectors/elasticsearch/src/server.ts +6 -0
- package/connectors/elasticsearch/src/tools.ts +110 -0
- package/connectors/fastmail/nimbus.extension.json +16 -0
- package/connectors/fastmail/src/jmap-core.ts +86 -0
- package/connectors/fastmail/src/server.ts +194 -0
- package/connectors/fastmail/src/tools.ts +143 -0
- package/connectors/figma/nimbus.extension.json +15 -0
- package/connectors/figma/src/search-filter.ts +24 -0
- package/connectors/figma/src/server.ts +117 -0
- package/connectors/firebase/nimbus.extension.json +15 -0
- package/connectors/firebase/src/search-filter.ts +30 -0
- package/connectors/firebase/src/server.ts +94 -0
- package/connectors/firebase/src/token.ts +41 -0
- package/connectors/flagsmith/nimbus.extension.json +15 -0
- package/connectors/flagsmith/src/search-filter.ts +29 -0
- package/connectors/flagsmith/src/server.ts +102 -0
- package/connectors/flux/nimbus.extension.json +16 -0
- package/connectors/flux/src/search-filter.ts +42 -0
- package/connectors/flux/src/server.ts +182 -0
- package/connectors/gcp/nimbus.extension.json +15 -0
- package/connectors/gcp/src/server.ts +140 -0
- package/connectors/github/nimbus.extension.json +15 -0
- package/connectors/github/src/server.ts +347 -0
- package/connectors/github-actions/nimbus.extension.json +15 -0
- package/connectors/github-actions/src/server.ts +213 -0
- package/connectors/gitlab/nimbus.extension.json +15 -0
- package/connectors/gitlab/src/server.ts +392 -0
- package/connectors/gmail/nimbus.extension.json +15 -0
- package/connectors/gmail/src/server.ts +277 -0
- package/connectors/google-drive/nimbus.extension.json +15 -0
- package/connectors/google-drive/src/drive-query.ts +3 -0
- package/connectors/google-drive/src/server.ts +531 -0
- package/connectors/google-meet/nimbus.extension.json +15 -0
- package/connectors/google-meet/src/server.ts +89 -0
- package/connectors/google-photos/nimbus.extension.json +15 -0
- package/connectors/google-photos/src/server.ts +139 -0
- package/connectors/grafana/nimbus.extension.json +15 -0
- package/connectors/grafana/src/server.ts +61 -0
- package/connectors/great-expectations/nimbus.extension.json +16 -0
- package/connectors/great-expectations/src/gx-parse.ts +292 -0
- package/connectors/great-expectations/src/server.ts +6 -0
- package/connectors/great-expectations/src/tools.ts +91 -0
- package/connectors/greenhouse/nimbus.extension.json +15 -0
- package/connectors/greenhouse/src/search-filter.ts +65 -0
- package/connectors/greenhouse/src/server.ts +67 -0
- package/connectors/hubspot/nimbus.extension.json +15 -0
- package/connectors/hubspot/src/search-filter.ts +28 -0
- package/connectors/hubspot/src/server.ts +81 -0
- package/connectors/iac/nimbus.extension.json +14 -0
- package/connectors/iac/src/server.ts +145 -0
- package/connectors/imap/nimbus.extension.json +16 -0
- package/connectors/imap/src/imap-core.ts +110 -0
- package/connectors/imap/src/server.ts +232 -0
- package/connectors/imap/src/tools.ts +40 -0
- package/connectors/intercom/nimbus.extension.json +15 -0
- package/connectors/intercom/src/search-filter.ts +46 -0
- package/connectors/intercom/src/server.ts +65 -0
- package/connectors/jenkins/nimbus.extension.json +15 -0
- package/connectors/jenkins/src/jenkins-api.ts +156 -0
- package/connectors/jenkins/src/server.ts +223 -0
- package/connectors/jira/nimbus.extension.json +15 -0
- package/connectors/jira/src/server.ts +309 -0
- package/connectors/kubernetes/nimbus.extension.json +15 -0
- package/connectors/kubernetes/src/server.ts +163 -0
- package/connectors/launchdarkly/nimbus.extension.json +15 -0
- package/connectors/launchdarkly/src/search-filter.ts +31 -0
- package/connectors/launchdarkly/src/server.ts +79 -0
- package/connectors/lever/nimbus.extension.json +15 -0
- package/connectors/lever/src/search-filter.ts +35 -0
- package/connectors/lever/src/server.ts +64 -0
- package/connectors/linear/nimbus.extension.json +15 -0
- package/connectors/linear/src/server.ts +467 -0
- package/connectors/localdb/nimbus.extension.json +16 -0
- package/connectors/localdb/src/server.ts +6 -0
- package/connectors/localdb/src/sql-scan.ts +158 -0
- package/connectors/localdb/src/tools.ts +67 -0
- package/connectors/looker/nimbus.extension.json +16 -0
- package/connectors/looker/src/search-filter.ts +22 -0
- package/connectors/looker/src/server.ts +254 -0
- package/connectors/mendeley/nimbus.extension.json +15 -0
- package/connectors/mendeley/src/search-filter.ts +68 -0
- package/connectors/mendeley/src/server.ts +59 -0
- package/connectors/mercury/nimbus.extension.json +15 -0
- package/connectors/mercury/src/search-filter.ts +11 -0
- package/connectors/mercury/src/server.ts +61 -0
- package/connectors/metabase/nimbus.extension.json +16 -0
- package/connectors/metabase/src/search-filter.ts +22 -0
- package/connectors/metabase/src/server.ts +83 -0
- package/connectors/miro/nimbus.extension.json +15 -0
- package/connectors/miro/src/search-filter.ts +24 -0
- package/connectors/miro/src/server.ts +76 -0
- package/connectors/mlflow/nimbus.extension.json +16 -0
- package/connectors/mlflow/src/search-filter.ts +38 -0
- package/connectors/mlflow/src/server.ts +167 -0
- package/connectors/monte-carlo/nimbus.extension.json +16 -0
- package/connectors/monte-carlo/src/search-filter.ts +11 -0
- package/connectors/monte-carlo/src/server.ts +241 -0
- package/connectors/netlify/nimbus.extension.json +15 -0
- package/connectors/netlify/src/search-filter.ts +37 -0
- package/connectors/netlify/src/server.ts +64 -0
- package/connectors/newrelic/nimbus.extension.json +15 -0
- package/connectors/newrelic/src/server.ts +48 -0
- package/connectors/notion/nimbus.extension.json +15 -0
- package/connectors/notion/src/kb-append.ts +23 -0
- package/connectors/notion/src/server.ts +343 -0
- package/connectors/obsidian/nimbus.extension.json +19 -0
- package/connectors/obsidian/src/server.ts +433 -0
- package/connectors/onedrive/nimbus.extension.json +15 -0
- package/connectors/onedrive/src/server.ts +256 -0
- package/connectors/outlook/nimbus.extension.json +15 -0
- package/connectors/outlook/src/server.ts +358 -0
- package/connectors/outlook/src/tool-scope-policy.ts +53 -0
- package/connectors/pagerduty/nimbus.extension.json +15 -0
- package/connectors/pagerduty/src/server.ts +140 -0
- package/connectors/pipedrive/nimbus.extension.json +15 -0
- package/connectors/pipedrive/src/search-filter.ts +11 -0
- package/connectors/pipedrive/src/server.ts +62 -0
- package/connectors/powerbi/nimbus.extension.json +16 -0
- package/connectors/powerbi/src/search-filter.ts +22 -0
- package/connectors/powerbi/src/server.ts +249 -0
- package/connectors/prefect/nimbus.extension.json +16 -0
- package/connectors/prefect/src/search-filter.ts +40 -0
- package/connectors/prefect/src/server.ts +94 -0
- package/connectors/protonmail/nimbus.extension.json +16 -0
- package/connectors/protonmail/src/mail-core.ts +96 -0
- package/connectors/protonmail/src/server.ts +231 -0
- package/connectors/protonmail/src/tools.ts +45 -0
- package/connectors/raindrop/nimbus.extension.json +15 -0
- package/connectors/raindrop/src/search-filter.ts +20 -0
- package/connectors/raindrop/src/server.ts +107 -0
- package/connectors/ramp/nimbus.extension.json +15 -0
- package/connectors/ramp/src/search-filter.ts +37 -0
- package/connectors/ramp/src/server.ts +109 -0
- package/connectors/readwise/nimbus.extension.json +15 -0
- package/connectors/readwise/src/search-filter.ts +64 -0
- package/connectors/readwise/src/server.ts +92 -0
- package/connectors/sagemaker/nimbus.extension.json +15 -0
- package/connectors/sagemaker/src/server.ts +6 -0
- package/connectors/sagemaker/src/tools.ts +121 -0
- package/connectors/salesforce/nimbus.extension.json +15 -0
- package/connectors/salesforce/src/search-filter.ts +23 -0
- package/connectors/salesforce/src/server.ts +94 -0
- package/connectors/semgrep/nimbus.extension.json +15 -0
- package/connectors/semgrep/src/search-filter.ts +31 -0
- package/connectors/semgrep/src/server.ts +108 -0
- package/connectors/sentry/nimbus.extension.json +15 -0
- package/connectors/sentry/src/server.ts +66 -0
- package/connectors/slack/nimbus.extension.json +15 -0
- package/connectors/slack/src/server.ts +360 -0
- package/connectors/snowflake/nimbus.extension.json +16 -0
- package/connectors/snowflake/src/search-filter.ts +26 -0
- package/connectors/snowflake/src/server.ts +236 -0
- package/connectors/snyk/nimbus.extension.json +15 -0
- package/connectors/snyk/src/search-filter.ts +28 -0
- package/connectors/snyk/src/server.ts +144 -0
- package/connectors/sonarqube/nimbus.extension.json +15 -0
- package/connectors/sonarqube/src/search-filter.ts +28 -0
- package/connectors/sonarqube/src/server.ts +115 -0
- package/connectors/stackoverflow/nimbus.extension.json +15 -0
- package/connectors/stackoverflow/src/search-filter.ts +52 -0
- package/connectors/stackoverflow/src/server.ts +81 -0
- package/connectors/storybook/nimbus.extension.json +16 -0
- package/connectors/storybook/src/server.ts +6 -0
- package/connectors/storybook/src/storybook-parse.ts +67 -0
- package/connectors/storybook/src/tools.ts +68 -0
- package/connectors/stripe/nimbus.extension.json +15 -0
- package/connectors/stripe/src/search-filter.ts +19 -0
- package/connectors/stripe/src/server.ts +65 -0
- package/connectors/superset/nimbus.extension.json +16 -0
- package/connectors/superset/src/search-filter.ts +22 -0
- package/connectors/superset/src/server.ts +119 -0
- package/connectors/tableau/nimbus.extension.json +16 -0
- package/connectors/tableau/src/search-filter.ts +22 -0
- package/connectors/tableau/src/server.ts +248 -0
- package/connectors/teams/nimbus.extension.json +20 -0
- package/connectors/teams/src/bot-send.ts +72 -0
- package/connectors/teams/src/server.ts +257 -0
- package/connectors/testflight/nimbus.extension.json +15 -0
- package/connectors/testflight/src/jwt.ts +27 -0
- package/connectors/testflight/src/search-filter.ts +30 -0
- package/connectors/testflight/src/server.ts +74 -0
- package/connectors/vercel/nimbus.extension.json +15 -0
- package/connectors/vercel/src/search-filter.ts +34 -0
- package/connectors/vercel/src/server.ts +79 -0
- package/connectors/vertex-ai/nimbus.extension.json +15 -0
- package/connectors/vertex-ai/src/server.ts +6 -0
- package/connectors/vertex-ai/src/tools.ts +145 -0
- package/connectors/wiz/nimbus.extension.json +15 -0
- package/connectors/wiz/src/search-filter.ts +50 -0
- package/connectors/wiz/src/server.ts +192 -0
- package/connectors/workday/nimbus.extension.json +19 -0
- package/connectors/workday/src/search-filter.ts +5 -0
- package/connectors/workday/src/server.ts +78 -0
- package/connectors/workday/src/tools.ts +1 -0
- package/connectors/zendesk/nimbus.extension.json +16 -0
- package/connectors/zendesk/src/search-filter.ts +11 -0
- package/connectors/zendesk/src/server.ts +77 -0
- package/connectors/zoom/nimbus.extension.json +15 -0
- package/connectors/zoom/src/encode-meeting-path.ts +5 -0
- package/connectors/zoom/src/recordings-window.ts +34 -0
- package/connectors/zoom/src/search-filter.ts +42 -0
- package/connectors/zoom/src/server.ts +98 -0
- package/connectors/zotero/nimbus.extension.json +15 -0
- package/connectors/zotero/src/search-filter.ts +81 -0
- package/connectors/zotero/src/server.ts +82 -0
- package/package.json +152 -0
- package/shared/atlassian-json-fetch.ts +42 -0
- package/shared/audit-chain.ts +133 -0
- package/shared/connector-mode.ts +60 -0
- package/shared/consent-kit.ts +323 -0
- package/shared/fetch-bearer-json.ts +18 -0
- package/shared/header-safe.ts +28 -0
- package/shared/imap-bodystructure.ts +113 -0
- package/shared/imap-mail-core.ts +57 -0
- package/shared/imap-tool-kit.ts +293 -0
- package/shared/join-api-path.ts +18 -0
- package/shared/kb-markdown.ts +142 -0
- package/shared/mcp-search-tool.ts +37 -0
- package/shared/mcp-tool-kit.ts +35 -0
- package/shared/nimbus-spawn.ts +128 -0
- package/shared/rest-tool-kit.ts +18 -0
- package/shared/run-cli-json.ts +55 -0
- package/shared/run-read-only-mcp-connector.ts +59 -0
- package/shared/safe-cli-arg.ts +55 -0
- package/shared/search-filter.ts +140 -0
- package/shared/strip-trailing-slashes.ts +7 -0
- package/shared/write-scope.ts +58 -0
- package/standalone/src/bin.ts +19 -0
- package/standalone/src/launcher.ts +186 -0
- package/standalone/tsconfig.json +8 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import {
|
|
5
|
+
createRegisterSimpleTool,
|
|
6
|
+
createZodToolRegistrar,
|
|
7
|
+
mcpJsonResult as jsonResult,
|
|
8
|
+
} from "../../../shared/mcp-tool-kit.ts";
|
|
9
|
+
import { runCliJson, runCliOk } from "../../../shared/run-cli-json.ts";
|
|
10
|
+
|
|
11
|
+
function azEnv(): Record<string, string | undefined> {
|
|
12
|
+
return { ...process.env } as Record<string, string | undefined>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function azJson(args: string[]): Promise<unknown> {
|
|
16
|
+
const cmd = ["az", ...args, "-o", "json"];
|
|
17
|
+
const r = await runCliJson(cmd, azEnv());
|
|
18
|
+
if (!r.ok) {
|
|
19
|
+
throw new Error(r.message);
|
|
20
|
+
}
|
|
21
|
+
return r.data ?? {};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const mcp = new McpServer({ name: "nimbus-azure", version: "0.1.0" });
|
|
25
|
+
|
|
26
|
+
import { createWriteToolRegistrar } from "../../../shared/consent-kit.ts";
|
|
27
|
+
|
|
28
|
+
const reg = createZodToolRegistrar(createRegisterSimpleTool(mcp));
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Every MUTATING azure tool goes through here. Outside the gateway this adds the
|
|
32
|
+
* consent gate, the write-scope allow-list, the mutation budget and the audit record; inside
|
|
33
|
+
* the gateway it is a pass-through, because executor.ts (I2) is the gate there.
|
|
34
|
+
*/
|
|
35
|
+
const registerWriteTool = createWriteToolRegistrar(mcp, {
|
|
36
|
+
connector: "azure",
|
|
37
|
+
scopeEnv: "NIMBUS_MCP_AZURE_WRITE_SCOPE",
|
|
38
|
+
scopeKinds: ["resource_group"],
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
reg(
|
|
42
|
+
"azure_app_service_list",
|
|
43
|
+
"List App Services in a resource group.",
|
|
44
|
+
z.object({
|
|
45
|
+
subscriptionId: z.string().min(1),
|
|
46
|
+
resourceGroup: z.string().min(1),
|
|
47
|
+
}),
|
|
48
|
+
async (p) =>
|
|
49
|
+
jsonResult(
|
|
50
|
+
await azJson([
|
|
51
|
+
"webapp",
|
|
52
|
+
"list",
|
|
53
|
+
"--subscription",
|
|
54
|
+
p.subscriptionId,
|
|
55
|
+
"--resource-group",
|
|
56
|
+
p.resourceGroup,
|
|
57
|
+
]),
|
|
58
|
+
),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
registerWriteTool(
|
|
62
|
+
"azure_app_service_restart",
|
|
63
|
+
{
|
|
64
|
+
mutates: "azure.app_service.restart",
|
|
65
|
+
recoverable: true,
|
|
66
|
+
scopeTargetOf: (p) => ({ kind: "resource_group", value: p.resourceGroup }),
|
|
67
|
+
},
|
|
68
|
+
"Restart an App Service.",
|
|
69
|
+
z.object({
|
|
70
|
+
subscriptionId: z.string().min(1),
|
|
71
|
+
resourceGroup: z.string().min(1),
|
|
72
|
+
name: z.string().min(1),
|
|
73
|
+
}),
|
|
74
|
+
async (p) => {
|
|
75
|
+
const r = await runCliOk(
|
|
76
|
+
[
|
|
77
|
+
"az",
|
|
78
|
+
"webapp",
|
|
79
|
+
"restart",
|
|
80
|
+
"--subscription",
|
|
81
|
+
p.subscriptionId,
|
|
82
|
+
"--resource-group",
|
|
83
|
+
p.resourceGroup,
|
|
84
|
+
"--name",
|
|
85
|
+
p.name,
|
|
86
|
+
],
|
|
87
|
+
azEnv(),
|
|
88
|
+
);
|
|
89
|
+
if (!r.ok) {
|
|
90
|
+
throw new Error(r.message);
|
|
91
|
+
}
|
|
92
|
+
return jsonResult({ ok: true });
|
|
93
|
+
},
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
registerWriteTool(
|
|
97
|
+
"azure_aks_node_pool_scale",
|
|
98
|
+
{
|
|
99
|
+
mutates: "azure.aks.node_pool.scale",
|
|
100
|
+
recoverable: true,
|
|
101
|
+
scopeTargetOf: (p) => ({ kind: "resource_group", value: p.resourceGroup }),
|
|
102
|
+
},
|
|
103
|
+
"Scale an AKS node pool.",
|
|
104
|
+
z.object({
|
|
105
|
+
subscriptionId: z.string().min(1),
|
|
106
|
+
resourceGroup: z.string().min(1),
|
|
107
|
+
clusterName: z.string().min(1),
|
|
108
|
+
poolName: z.string().min(1),
|
|
109
|
+
nodeCount: z.number().int().min(0),
|
|
110
|
+
}),
|
|
111
|
+
async (p) => {
|
|
112
|
+
const r = await runCliOk(
|
|
113
|
+
[
|
|
114
|
+
"az",
|
|
115
|
+
"aks",
|
|
116
|
+
"nodepool",
|
|
117
|
+
"scale",
|
|
118
|
+
"--subscription",
|
|
119
|
+
p.subscriptionId,
|
|
120
|
+
"--resource-group",
|
|
121
|
+
p.resourceGroup,
|
|
122
|
+
"--cluster-name",
|
|
123
|
+
p.clusterName,
|
|
124
|
+
"--name",
|
|
125
|
+
p.poolName,
|
|
126
|
+
"--node-count",
|
|
127
|
+
String(p.nodeCount),
|
|
128
|
+
],
|
|
129
|
+
azEnv(),
|
|
130
|
+
);
|
|
131
|
+
if (!r.ok) {
|
|
132
|
+
throw new Error(r.message);
|
|
133
|
+
}
|
|
134
|
+
return jsonResult({ ok: true });
|
|
135
|
+
},
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
const transport = new StdioServerTransport();
|
|
139
|
+
await mcp.connect(transport);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "com.nimbus.bigeye",
|
|
3
|
+
"displayName": "Bigeye",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Bigeye connector. Indexes Bigeye data-quality issues as `data_quality_test` items in the local index and exposes read tools (`bigeye_list`, `bigeye_get`, `bigeye_search`) plus HITL-gated issue-lifecycle write tools (`bigeye_issue_acknowledge`, `bigeye_issue_resolve`). Uses a Bearer API key against a per-tenant Bigeye instance. The per-tenant host is derived from bigeye.base_url at spawn time (like Looker/Tableau).",
|
|
6
|
+
"author": "Nimbus",
|
|
7
|
+
"entrypoint": "dist/server.js",
|
|
8
|
+
"runtime": "bun",
|
|
9
|
+
"permissions": {
|
|
10
|
+
"network": [],
|
|
11
|
+
"filesystem": { "read": [], "write": [] }
|
|
12
|
+
},
|
|
13
|
+
"hitlRequired": ["write"],
|
|
14
|
+
"syncInterval": 600,
|
|
15
|
+
"minNimbusVersion": "0.5.0"
|
|
16
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
asRecord,
|
|
3
|
+
makeQueryFilter,
|
|
4
|
+
type SearchMatchOptions,
|
|
5
|
+
} from "../../../shared/search-filter.ts";
|
|
6
|
+
|
|
7
|
+
export type BigeyeSearchMatchOptions = SearchMatchOptions;
|
|
8
|
+
|
|
9
|
+
function stringAt(row: Record<string, unknown>, key: string): string {
|
|
10
|
+
const v = row[key];
|
|
11
|
+
return typeof v === "string" ? v : "";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function fieldsOf(item: unknown): readonly string[] | null {
|
|
15
|
+
const row = asRecord(item);
|
|
16
|
+
if (row === undefined) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return [stringAt(row, "summary"), stringAt(row, "title"), stringAt(row, "description")];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const filterBigeyeIssues = makeQueryFilter(fieldsOf);
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type ConsentServer, createWriteToolRegistrar } from "../../../shared/consent-kit.ts";
|
|
3
|
+
import { searchToolInputSchema } from "../../../shared/mcp-search-tool.ts";
|
|
4
|
+
import { fetchWithTimeout, mcpJsonResult as jsonResult } from "../../../shared/mcp-tool-kit.ts";
|
|
5
|
+
import {
|
|
6
|
+
runReadOnlyMcpConnector,
|
|
7
|
+
type ZodToolRegistrar,
|
|
8
|
+
} from "../../../shared/run-read-only-mcp-connector.ts";
|
|
9
|
+
import { filterBigeyeIssues } from "./search-filter.ts";
|
|
10
|
+
|
|
11
|
+
function apiBase(): string {
|
|
12
|
+
const v = process.env["BIGEYE_BASE_URL"]?.trim();
|
|
13
|
+
if (v === undefined || v === "") {
|
|
14
|
+
throw new Error("BIGEYE_BASE_URL is not set");
|
|
15
|
+
}
|
|
16
|
+
return v.endsWith("/") ? v.slice(0, -1) : v;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function authHeader(): Record<string, string> {
|
|
20
|
+
const k = process.env["BIGEYE_API_KEY"]?.trim();
|
|
21
|
+
if (k === undefined || k === "") {
|
|
22
|
+
throw new Error("BIGEYE_API_KEY is not set");
|
|
23
|
+
}
|
|
24
|
+
return { Authorization: `Bearer ${k}`, Accept: "application/json" };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** One page of issues (`GET /api/v1/issues?limit&offset`), tolerant of array / `{issues}` / `{data}`. */
|
|
28
|
+
async function fetchIssues(limit: number, offset: number): Promise<unknown[]> {
|
|
29
|
+
const url = `${apiBase()}/api/v1/issues?limit=${String(limit)}&offset=${String(offset)}`;
|
|
30
|
+
const res = await fetchWithTimeout(url, { headers: authHeader() });
|
|
31
|
+
const text = await res.text();
|
|
32
|
+
if (!res.ok) {
|
|
33
|
+
throw new Error(`Bigeye ${String(res.status)}: ${text.slice(0, 400)}`);
|
|
34
|
+
}
|
|
35
|
+
const parsed = JSON.parse(text) as unknown;
|
|
36
|
+
if (Array.isArray(parsed)) {
|
|
37
|
+
return parsed;
|
|
38
|
+
}
|
|
39
|
+
if (parsed !== null && typeof parsed === "object") {
|
|
40
|
+
const root = parsed as Record<string, unknown>;
|
|
41
|
+
if (Array.isArray(root["issues"])) return root["issues"];
|
|
42
|
+
if (Array.isArray(root["data"])) return root["data"];
|
|
43
|
+
}
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function issueId(item: unknown): string {
|
|
48
|
+
if (item === null || typeof item !== "object" || Array.isArray(item)) return "";
|
|
49
|
+
const row = item as Record<string, unknown>;
|
|
50
|
+
const v = row["id"];
|
|
51
|
+
if (typeof v === "string") return v;
|
|
52
|
+
if (typeof v === "number") return String(v);
|
|
53
|
+
return "";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Update a Bigeye issue status via `POST /api/v1/issues`. */
|
|
57
|
+
async function updateIssueStatus(issueId: string, status: string): Promise<void> {
|
|
58
|
+
const base = apiBase();
|
|
59
|
+
const res = await fetchWithTimeout(`${base}/api/v1/issues`, {
|
|
60
|
+
method: "POST",
|
|
61
|
+
headers: { ...authHeader(), "Content-Type": "application/json" },
|
|
62
|
+
body: JSON.stringify({ issueId, status }),
|
|
63
|
+
});
|
|
64
|
+
if (!res.ok) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Bigeye updateIssue ${String(res.status)}: ${(await res.text()).slice(0, 400)}`,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function registerBigeyeTools(reg: ZodToolRegistrar, server: unknown): void {
|
|
72
|
+
// Despite the read-only helper's name, this connector exposes write tools. The consent
|
|
73
|
+
// kit needs the real server, which the helper now passes through as its second argument.
|
|
74
|
+
const registerWriteTool = createWriteToolRegistrar(server as ConsentServer, {
|
|
75
|
+
connector: "bigeye",
|
|
76
|
+
scopeEnv: "NIMBUS_MCP_BIGEYE_WRITE_SCOPE",
|
|
77
|
+
scopeKinds: ["issue"],
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
reg(
|
|
81
|
+
"bigeye_list",
|
|
82
|
+
"List Bigeye data-quality issues (`GET /api/v1/issues`). Paginated: `cursor` (offset) + `limit` (default 200, max 500) → `{ items, nextCursor }`.",
|
|
83
|
+
z.object({
|
|
84
|
+
cursor: z.string().nullable().optional(),
|
|
85
|
+
limit: z.number().int().min(1).max(500).optional(),
|
|
86
|
+
}),
|
|
87
|
+
async (p) => {
|
|
88
|
+
const limit = p.limit ?? 200;
|
|
89
|
+
// null / undefined / "" / non-numeric / negative all clamp to offset 0; fractional truncates.
|
|
90
|
+
const offset = Math.max(0, Math.trunc(Number(p.cursor) || 0));
|
|
91
|
+
const issues = await fetchIssues(limit, offset);
|
|
92
|
+
const nextCursor = issues.length === limit ? String(offset + limit) : null;
|
|
93
|
+
return jsonResult({ items: issues, nextCursor });
|
|
94
|
+
},
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
reg(
|
|
98
|
+
"bigeye_get",
|
|
99
|
+
"Fetch one Bigeye data-quality issue by its id. Throws when the issue is not found.",
|
|
100
|
+
z.object({
|
|
101
|
+
id: z.string().min(1),
|
|
102
|
+
}),
|
|
103
|
+
async (p) => {
|
|
104
|
+
const issues = await fetchIssues(500, 0);
|
|
105
|
+
const found = issues.find((item) => issueId(item) === p.id);
|
|
106
|
+
if (found === undefined) {
|
|
107
|
+
throw new Error(`Bigeye issue not found: ${p.id}`);
|
|
108
|
+
}
|
|
109
|
+
return jsonResult(found);
|
|
110
|
+
},
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
reg(
|
|
114
|
+
"bigeye_search",
|
|
115
|
+
"Substring search across Bigeye data-quality issues. Matches the query (case-insensitive) against issue summary, title, and description. Returns a `{ matches: [...] }` envelope.",
|
|
116
|
+
searchToolInputSchema(200),
|
|
117
|
+
async (p) => {
|
|
118
|
+
const issues = await fetchIssues(500, 0);
|
|
119
|
+
const matches = filterBigeyeIssues(issues, { query: p.query, limit: p.limit });
|
|
120
|
+
return jsonResult({ matches });
|
|
121
|
+
},
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
registerWriteTool(
|
|
125
|
+
"bigeye_issue_acknowledge",
|
|
126
|
+
{
|
|
127
|
+
mutates: "bigeye.issue.acknowledge",
|
|
128
|
+
recoverable: true,
|
|
129
|
+
scopeTargetOf: (p) => ({ kind: "issue", value: p.issueId }),
|
|
130
|
+
},
|
|
131
|
+
"Acknowledge a Bigeye issue.",
|
|
132
|
+
z.object({ issueId: z.string().min(1) }),
|
|
133
|
+
async (p) => {
|
|
134
|
+
await updateIssueStatus(p.issueId, "ISSUE_STATUS_ACKNOWLEDGED");
|
|
135
|
+
return jsonResult({ status: "ok", issueId: p.issueId });
|
|
136
|
+
},
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
registerWriteTool(
|
|
140
|
+
"bigeye_issue_resolve",
|
|
141
|
+
{
|
|
142
|
+
mutates: "bigeye.issue.resolve",
|
|
143
|
+
recoverable: true,
|
|
144
|
+
scopeTargetOf: (p) => ({ kind: "issue", value: p.issueId }),
|
|
145
|
+
},
|
|
146
|
+
"Resolve (close) a Bigeye issue.",
|
|
147
|
+
z.object({ issueId: z.string().min(1) }),
|
|
148
|
+
async (p) => {
|
|
149
|
+
await updateIssueStatus(p.issueId, "ISSUE_STATUS_CLOSED");
|
|
150
|
+
return jsonResult({ status: "ok", issueId: p.issueId });
|
|
151
|
+
},
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Exported so the bundled-connector registry can start this server explicitly: `import.meta.main`
|
|
156
|
+
// is false under an import, and the module must stay importable by tests without connecting stdio.
|
|
157
|
+
export async function startConnector(): Promise<void> {
|
|
158
|
+
await runReadOnlyMcpConnector("nimbus-bigeye", registerBigeyeTools);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (import.meta.main) await startConnector();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "com.nimbus.bigquery",
|
|
3
|
+
"displayName": "BigQuery",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Google BigQuery metadata connector (Tier-3, no-row-data). Indexes datasets, tables, and schema field names/types via the BigQuery REST metadata API — never row, cell, or query-result data. Reuses the existing GCP service-account credentials via the gcloud CLI. Read-only; no write tools.",
|
|
6
|
+
"author": "Nimbus",
|
|
7
|
+
"entrypoint": "dist/server.js",
|
|
8
|
+
"runtime": "bun",
|
|
9
|
+
"permissions": {
|
|
10
|
+
"network": ["bigquery.googleapis.com", "oauth2.googleapis.com", "www.googleapis.com"]
|
|
11
|
+
},
|
|
12
|
+
"hitlRequired": [],
|
|
13
|
+
"syncInterval": 600,
|
|
14
|
+
"minNimbusVersion": "0.2.0"
|
|
15
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { mcpJsonResult as jsonResult } from "../../../shared/mcp-tool-kit.ts";
|
|
3
|
+
import { nimbusSpawn } from "../../../shared/nimbus-spawn.ts";
|
|
4
|
+
import type { ZodToolRegistrar } from "../../../shared/run-read-only-mcp-connector.ts";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* BigQuery (Tier-3, metadata-only) MCP tool surface. ALL tools index schema /
|
|
8
|
+
* METADATA only (datasets, tables, schema field names + types, row COUNTS, byte
|
|
9
|
+
* sizes, timestamps). NONE fetch row / cell / query-result data — no `bq query`,
|
|
10
|
+
* no `bq head`, no `tabledata.list`. The names are introspected by the
|
|
11
|
+
* `assertNoRowDataTools` contract test, so they must never contain a row-data
|
|
12
|
+
* segment (query/rows/sample/scan/preview/head/export/…).
|
|
13
|
+
*/
|
|
14
|
+
export const BIGQUERY_TOOL_NAMES = ["bigquery_list", "bigquery_get", "bigquery_search"] as const;
|
|
15
|
+
|
|
16
|
+
const BASE = "https://bigquery.googleapis.com/bigquery/v2";
|
|
17
|
+
|
|
18
|
+
function project(explicit?: string): string {
|
|
19
|
+
const p = (explicit ?? process.env["BIGQUERY_PROJECT"])?.trim();
|
|
20
|
+
if (p === undefined || p === "") {
|
|
21
|
+
throw new Error("BIGQUERY_PROJECT is not set and no project argument was provided");
|
|
22
|
+
}
|
|
23
|
+
return p;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function gcloudEnv(): Record<string, string | undefined> {
|
|
27
|
+
const e = { ...process.env } as Record<string, string | undefined>;
|
|
28
|
+
const cf = process.env["GOOGLE_APPLICATION_CREDENTIALS"]?.trim();
|
|
29
|
+
if (cf !== undefined && cf !== "") {
|
|
30
|
+
e["GOOGLE_APPLICATION_CREDENTIALS"] = cf;
|
|
31
|
+
}
|
|
32
|
+
return e;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Mint a short-lived access token via `gcloud auth print-access-token`. */
|
|
36
|
+
async function accessToken(): Promise<string> {
|
|
37
|
+
const { code, stdout, stderr } = await nimbusSpawn(
|
|
38
|
+
["gcloud", "auth", "print-access-token"],
|
|
39
|
+
// Restores GOOGLE_APPLICATION_CREDENTIALS when set; nimbusSpawn already merges process.env.
|
|
40
|
+
gcloudEnv(),
|
|
41
|
+
);
|
|
42
|
+
const out = stdout.trim();
|
|
43
|
+
const err = stderr.trim();
|
|
44
|
+
if (code !== 0 || out === "") {
|
|
45
|
+
throw new Error(`gcloud auth print-access-token failed: ${err.slice(0, 300)}`);
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function bqGet(token: string, path: string): Promise<unknown> {
|
|
51
|
+
const res = await fetch(`${BASE}${path}`, {
|
|
52
|
+
headers: { Authorization: `Bearer ${token}`, Accept: "application/json" },
|
|
53
|
+
});
|
|
54
|
+
const text = await res.text();
|
|
55
|
+
if (!res.ok) {
|
|
56
|
+
throw new Error(`BigQuery ${String(res.status)}: ${text.slice(0, 400)}`);
|
|
57
|
+
}
|
|
58
|
+
return JSON.parse(text) as unknown;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function isRecord(v: unknown): v is Record<string, unknown> {
|
|
62
|
+
return v !== null && typeof v === "object" && !Array.isArray(v);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function strField(r: Record<string, unknown>, key: string): string {
|
|
66
|
+
const v = r[key];
|
|
67
|
+
return typeof v === "string" ? v : "";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function tableMatches(entry: unknown, q: string): boolean {
|
|
71
|
+
if (!isRecord(entry)) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
const ref = entry["tableReference"];
|
|
75
|
+
const datasetId = isRecord(ref) ? strField(ref, "datasetId") : "";
|
|
76
|
+
const tableId = isRecord(ref) ? strField(ref, "tableId") : "";
|
|
77
|
+
const friendly = strField(entry, "friendlyName");
|
|
78
|
+
const hay = `${datasetId}.${tableId} ${friendly}`.toLowerCase();
|
|
79
|
+
return hay.includes(q.toLowerCase());
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function datasetMatches(entry: unknown, q: string): boolean {
|
|
83
|
+
if (!isRecord(entry)) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
const ref = entry["datasetReference"];
|
|
87
|
+
const datasetId = isRecord(ref) ? strField(ref, "datasetId") : "";
|
|
88
|
+
return datasetId.toLowerCase().includes(q.toLowerCase());
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function asArray(parsed: unknown, key: string): unknown[] {
|
|
92
|
+
if (!isRecord(parsed)) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
const arr = parsed[key];
|
|
96
|
+
return Array.isArray(arr) ? arr : [];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Register the read-only, metadata-only BigQuery tools onto the given registrar.
|
|
101
|
+
* Shared between `server.ts` (live) and the contract test (introspection).
|
|
102
|
+
*/
|
|
103
|
+
export function registerBigqueryTools(reg: ZodToolRegistrar): void {
|
|
104
|
+
reg(
|
|
105
|
+
"bigquery_list",
|
|
106
|
+
"List BigQuery datasets, or the tables in a dataset — METADATA ONLY. With no `dataset` argument, lists datasets (`GET /projects/<project>/datasets`). With `dataset` set, lists that dataset's tables (`GET /projects/<project>/datasets/<dataset>/tables`) — each entry carries `tableReference`, `type`, and `creationTime`. Never returns row or cell data.",
|
|
107
|
+
z.object({
|
|
108
|
+
project: z.string().min(1).optional(),
|
|
109
|
+
dataset: z.string().min(1).optional(),
|
|
110
|
+
}),
|
|
111
|
+
async (p) => {
|
|
112
|
+
const token = await accessToken();
|
|
113
|
+
const proj = project(p.project);
|
|
114
|
+
if (p.dataset === undefined) {
|
|
115
|
+
return jsonResult(
|
|
116
|
+
await bqGet(token, `/projects/${encodeURIComponent(proj)}/datasets?maxResults=200`),
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
return jsonResult(
|
|
120
|
+
await bqGet(
|
|
121
|
+
token,
|
|
122
|
+
`/projects/${encodeURIComponent(proj)}/datasets/${encodeURIComponent(p.dataset)}/tables?maxResults=200`,
|
|
123
|
+
),
|
|
124
|
+
);
|
|
125
|
+
},
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
reg(
|
|
129
|
+
"bigquery_get",
|
|
130
|
+
"Fetch one BigQuery table's schema + METADATA (`GET /projects/<project>/datasets/<dataset>/tables/<table>`). Returns the table object including `schema.fields` (field names + types only), `numRows`, `numBytes`, `creationTime`, and `lastModifiedTime`. Row COUNTS and byte sizes are metadata, NOT row data; no cell values are returned.",
|
|
131
|
+
z.object({
|
|
132
|
+
project: z.string().min(1).optional(),
|
|
133
|
+
dataset: z.string().min(1),
|
|
134
|
+
table: z.string().min(1),
|
|
135
|
+
}),
|
|
136
|
+
async (p) => {
|
|
137
|
+
const token = await accessToken();
|
|
138
|
+
const proj = project(p.project);
|
|
139
|
+
return jsonResult(
|
|
140
|
+
await bqGet(
|
|
141
|
+
token,
|
|
142
|
+
`/projects/${encodeURIComponent(proj)}/datasets/${encodeURIComponent(p.dataset)}/tables/${encodeURIComponent(p.table)}`,
|
|
143
|
+
),
|
|
144
|
+
);
|
|
145
|
+
},
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
reg(
|
|
149
|
+
"bigquery_search",
|
|
150
|
+
"Substring search over dataset and table NAMES (case-insensitive) — METADATA ONLY. With no `dataset`, searches dataset ids. With `dataset` set, searches that dataset's table ids + friendly names. Returns a `{ matches: [...] }` envelope of metadata entries. Never queries or samples row data.",
|
|
151
|
+
z.object({
|
|
152
|
+
project: z.string().min(1).optional(),
|
|
153
|
+
dataset: z.string().min(1).optional(),
|
|
154
|
+
query: z.string().min(1),
|
|
155
|
+
}),
|
|
156
|
+
async (p) => {
|
|
157
|
+
const token = await accessToken();
|
|
158
|
+
const proj = project(p.project);
|
|
159
|
+
if (p.dataset === undefined) {
|
|
160
|
+
const root = await bqGet(
|
|
161
|
+
token,
|
|
162
|
+
`/projects/${encodeURIComponent(proj)}/datasets?maxResults=200`,
|
|
163
|
+
);
|
|
164
|
+
const matches = asArray(root, "datasets").filter((d) => datasetMatches(d, p.query));
|
|
165
|
+
return jsonResult({ matches });
|
|
166
|
+
}
|
|
167
|
+
const root = await bqGet(
|
|
168
|
+
token,
|
|
169
|
+
`/projects/${encodeURIComponent(proj)}/datasets/${encodeURIComponent(p.dataset)}/tables?maxResults=200`,
|
|
170
|
+
);
|
|
171
|
+
const matches = asArray(root, "tables").filter((t) => tableMatches(t, p.query));
|
|
172
|
+
return jsonResult({ matches });
|
|
173
|
+
},
|
|
174
|
+
);
|
|
175
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "com.nimbus.bitbucket",
|
|
3
|
+
"displayName": "Bitbucket Cloud",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Bitbucket Cloud REST connector (repositories, pull requests). Mutations require Gateway HITL.",
|
|
6
|
+
"author": "Nimbus",
|
|
7
|
+
"entrypoint": "dist/server.js",
|
|
8
|
+
"runtime": "bun",
|
|
9
|
+
"permissions": {
|
|
10
|
+
"network": ["api.bitbucket.org", "bitbucket.org"]
|
|
11
|
+
},
|
|
12
|
+
"hitlRequired": ["write", "delete"],
|
|
13
|
+
"syncInterval": 300,
|
|
14
|
+
"minNimbusVersion": "0.2.0"
|
|
15
|
+
}
|