@neon/tools 0.8.0 → 1.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/README.md +26 -7
- package/dist/generated/zod.gen.d.ts.map +1 -1
- package/dist/generated/zod.gen.js +1119 -1119
- package/dist/lib/ergonomic/bind.d.ts.map +1 -1
- package/dist/lib/ergonomic/bind.js +1 -1
- package/dist/lib/ergonomic/catalog.d.ts +186 -2
- package/dist/lib/ergonomic/catalog.d.ts.map +1 -1
- package/dist/lib/ergonomic/catalog.js +4 -2
- package/dist/lib/ergonomic/composed.d.ts +253 -3
- package/dist/lib/ergonomic/composed.d.ts.map +1 -1
- package/dist/lib/ergonomic/composed.js +78 -18
- package/dist/lib/ergonomic/ids.d.ts +2 -2
- package/dist/lib/ergonomic/ids.d.ts.map +1 -1
- package/dist/lib/ergonomic/ids.js +3 -5
- package/dist/lib/mcp-json-schema.d.ts +15 -0
- package/dist/lib/mcp-json-schema.d.ts.map +1 -0
- package/dist/lib/mcp-json-schema.js +31 -0
- package/dist/lib/mcp-register.d.ts +14 -0
- package/dist/lib/mcp-register.d.ts.map +1 -0
- package/dist/lib/mcp-register.js +61 -0
- package/dist/mcp-v1.d.ts +4 -2
- package/dist/mcp-v1.d.ts.map +1 -1
- package/dist/mcp-v1.js +6 -1
- package/dist/mcp.d.ts +5 -11
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +4 -56
- package/dist/operations.gen.js +167 -167
- package/package.json +2 -2
|
@@ -14,17 +14,38 @@ const readAnnotations = {
|
|
|
14
14
|
const pooledField = z.boolean().describe("Return a pooled connection string. Default true. Set false for a direct connection.").optional();
|
|
15
15
|
const branchCreateFields = zBranchCreateRequest.shape.branch.unwrap().shape;
|
|
16
16
|
const projectCreateFields = zCreateProjectBody.shape.project.shape;
|
|
17
|
-
const
|
|
17
|
+
const computeSettingsSchema = z.strictObject({
|
|
18
|
+
min_cu: zComputeUnit.optional(),
|
|
19
|
+
max_cu: zComputeUnit.optional(),
|
|
20
|
+
suspend_timeout_seconds: zSuspendTimeoutSeconds.optional()
|
|
21
|
+
}).optional();
|
|
22
|
+
const mapCompute = (compute) => compute === void 0 ? void 0 : {
|
|
23
|
+
minCu: compute.min_cu,
|
|
24
|
+
maxCu: compute.max_cu,
|
|
25
|
+
suspendTimeoutSeconds: compute.suspend_timeout_seconds
|
|
26
|
+
};
|
|
27
|
+
const NO_COMPUTE_WITH_COMPUTE = "Pass compute settings or no_compute, not both.";
|
|
28
|
+
const createBranchInputSchema = z.strictObject({
|
|
18
29
|
project_id: zCreateProjectBranchPath.shape.project_id,
|
|
19
30
|
name: branchCreateFields.name,
|
|
20
31
|
parent_id: branchCreateFields.parent_id,
|
|
21
|
-
compute:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
32
|
+
compute: computeSettingsSchema,
|
|
33
|
+
no_compute: z.boolean().describe("Skip the read-write endpoint. Default false. Cannot be combined with compute.").optional()
|
|
34
|
+
}).superRefine((value, ctx) => {
|
|
35
|
+
if (value.no_compute === true && value.compute !== void 0) ctx.addIssue({
|
|
36
|
+
code: "custom",
|
|
37
|
+
message: NO_COMPUTE_WITH_COMPUTE,
|
|
38
|
+
path: ["no_compute"]
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
const createBranchAndConnectInputSchema = z.strictObject({
|
|
42
|
+
project_id: zCreateProjectBranchPath.shape.project_id,
|
|
43
|
+
name: branchCreateFields.name,
|
|
44
|
+
parent_id: branchCreateFields.parent_id,
|
|
45
|
+
compute: computeSettingsSchema,
|
|
26
46
|
pooled: pooledField
|
|
27
47
|
});
|
|
48
|
+
const createProjectInputSchema = z.strictObject({ ...projectCreateFields });
|
|
28
49
|
const createProjectAndConnectInputSchema = z.strictObject({
|
|
29
50
|
...projectCreateFields,
|
|
30
51
|
pooled: pooledField
|
|
@@ -74,12 +95,39 @@ const setScheduleInputSchema = z.strictObject({
|
|
|
74
95
|
frequency: snapshotFrequency
|
|
75
96
|
}))
|
|
76
97
|
});
|
|
77
|
-
const
|
|
78
|
-
operationId: "branches.
|
|
79
|
-
id: publishedId("branches.
|
|
80
|
-
title: "Create branch
|
|
98
|
+
const createBranchTool = (options) => bindTool(options, {
|
|
99
|
+
operationId: "branches.create",
|
|
100
|
+
id: publishedId("branches.create"),
|
|
101
|
+
title: "Create branch",
|
|
102
|
+
description: "Create a branch with a read-write endpoint by default. Pass no_compute to skip the endpoint. The call waits until operation-backed provisioning finishes, up to five minutes by default. Does not return a connection string; use branches.createAndConnect or postgres.connectionString for that.",
|
|
103
|
+
inputSchema: createBranchInputSchema,
|
|
104
|
+
annotations: writeAnnotations,
|
|
105
|
+
requiresApproval: true,
|
|
106
|
+
metadata: {
|
|
107
|
+
method: "POST",
|
|
108
|
+
path: "/projects/{project_id}/branches",
|
|
109
|
+
stability: "stable",
|
|
110
|
+
deprecated: false,
|
|
111
|
+
tags: ["Branch"]
|
|
112
|
+
}
|
|
113
|
+
}, (neon, input, signal) => {
|
|
114
|
+
if (input.no_compute === true) return neon.branches.create(input.project_id, {
|
|
115
|
+
name: input.name,
|
|
116
|
+
parent_id: input.parent_id,
|
|
117
|
+
noCompute: true
|
|
118
|
+
}, { signal });
|
|
119
|
+
return neon.branches.create(input.project_id, {
|
|
120
|
+
name: input.name,
|
|
121
|
+
parent_id: input.parent_id,
|
|
122
|
+
compute: mapCompute(input.compute)
|
|
123
|
+
}, { signal });
|
|
124
|
+
});
|
|
125
|
+
const createBranchAndConnectTool = (options) => bindTool(options, {
|
|
126
|
+
operationId: "branches.createAndConnect",
|
|
127
|
+
id: publishedId("branches.createAndConnect"),
|
|
128
|
+
title: "Create branch and connect",
|
|
81
129
|
description: "Create a branch with a read-write endpoint and return its connection string. The call waits until operation-backed provisioning finishes, up to five minutes by default.",
|
|
82
|
-
inputSchema:
|
|
130
|
+
inputSchema: createBranchAndConnectInputSchema,
|
|
83
131
|
annotations: writeAnnotations,
|
|
84
132
|
requiresApproval: true,
|
|
85
133
|
metadata: {
|
|
@@ -89,18 +137,30 @@ const createBranchWithComputeTool = (options) => bindTool(options, {
|
|
|
89
137
|
deprecated: false,
|
|
90
138
|
tags: ["Branch"]
|
|
91
139
|
}
|
|
92
|
-
}, (neon, input, signal) => neon.branches.
|
|
140
|
+
}, (neon, input, signal) => neon.branches.createAndConnect(input.project_id, {
|
|
93
141
|
name: input.name,
|
|
94
142
|
parentId: input.parent_id,
|
|
95
|
-
compute: input.compute
|
|
96
|
-
minCu: input.compute.min_cu,
|
|
97
|
-
maxCu: input.compute.max_cu,
|
|
98
|
-
suspendTimeoutSeconds: input.compute.suspend_timeout_seconds
|
|
99
|
-
}
|
|
143
|
+
compute: mapCompute(input.compute)
|
|
100
144
|
}, {
|
|
101
145
|
signal,
|
|
102
146
|
...input.pooled === void 0 ? {} : { pooled: input.pooled }
|
|
103
147
|
}));
|
|
148
|
+
const createProjectTool = (options) => bindTool(options, {
|
|
149
|
+
operationId: "projects.create",
|
|
150
|
+
id: publishedId("projects.create"),
|
|
151
|
+
title: "Create project",
|
|
152
|
+
description: "Create a project. The API always provisions a default branch with read-write compute. The call waits until operation-backed provisioning finishes, up to five minutes by default. Does not return a connection string; use projects.createAndConnect or postgres.connectionString for that.",
|
|
153
|
+
inputSchema: createProjectInputSchema,
|
|
154
|
+
annotations: writeAnnotations,
|
|
155
|
+
requiresApproval: true,
|
|
156
|
+
metadata: {
|
|
157
|
+
method: "POST",
|
|
158
|
+
path: "/projects",
|
|
159
|
+
stability: "stable",
|
|
160
|
+
deprecated: false,
|
|
161
|
+
tags: ["Project"]
|
|
162
|
+
}
|
|
163
|
+
}, (neon, input, signal) => neon.projects.create(input, { signal }));
|
|
104
164
|
const createProjectAndConnectTool = (options) => bindTool(options, {
|
|
105
165
|
operationId: "projects.createAndConnect",
|
|
106
166
|
id: publishedId("projects.createAndConnect"),
|
|
@@ -238,4 +298,4 @@ const setScheduleTool = (options) => bindTool(options, {
|
|
|
238
298
|
}
|
|
239
299
|
}, (neon, input, signal) => neon.snapshots.setSchedule(input.project_id, input.branch_id, { schedule: input.schedule }, { signal }));
|
|
240
300
|
//#endregion
|
|
241
|
-
export { compareSchemaInputSchema, compareSchemaTool, connectionStringInputSchema, connectionStringTool,
|
|
301
|
+
export { compareSchemaInputSchema, compareSchemaTool, connectionStringInputSchema, connectionStringTool, createBranchAndConnectInputSchema, createBranchAndConnectTool, createBranchInputSchema, createBranchTool, createProjectAndConnectInputSchema, createProjectAndConnectTool, createProjectInputSchema, createProjectTool, getDefaultInputSchema, getDefaultTool, resetFromParentInputSchema, resetFromParentTool, restoreSnapshotInputSchema, restoreSnapshotTool, setScheduleInputSchema, setScheduleTool };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export declare const hiddenToolIds: readonly ["operations.waitFor", "
|
|
1
|
+
export declare const hiddenToolIds: readonly ["operations.waitFor", "postgres.roles.password", "storage.objects.get"];
|
|
2
2
|
export type HiddenToolId = (typeof hiddenToolIds)[number];
|
|
3
|
-
export declare const toolIds: readonly ["projects.list", "projects.get", "projects.createAndConnect", "projects.update", "projects.delete", "projects.recover", "projects.transfer", "projects.transferFromUser", "projects.permissions.list", "projects.permissions.grant", "projects.permissions.revoke", "projects.members.list", "projects.members.setRole", "projects.members.removeRole", "branches.list", "branches.get", "branches.
|
|
3
|
+
export declare const toolIds: readonly ["projects.list", "projects.get", "projects.create", "projects.createAndConnect", "projects.update", "projects.delete", "projects.recover", "projects.transfer", "projects.transferFromUser", "projects.permissions.list", "projects.permissions.grant", "projects.permissions.revoke", "projects.members.list", "projects.members.setRole", "projects.members.removeRole", "branches.list", "branches.get", "branches.create", "branches.createAndConnect", "branches.update", "branches.delete", "branches.getDefault", "branches.setDefault", "branches.resetFromParent", "branches.compareSchema", "branches.finalizeRestore", "postgres.connectionString", "postgres.endpoints.list", "postgres.endpoints.listByBranch", "postgres.endpoints.get", "postgres.endpoints.create", "postgres.endpoints.update", "postgres.endpoints.delete", "postgres.endpoints.start", "postgres.endpoints.suspend", "postgres.endpoints.restart", "postgres.roles.list", "postgres.roles.get", "postgres.roles.create", "postgres.roles.delete", "postgres.roles.resetPassword", "postgres.databases.list", "postgres.databases.get", "postgres.databases.create", "postgres.databases.update", "postgres.databases.delete", "postgres.dataApi.get", "postgres.dataApi.create", "postgres.dataApi.update", "postgres.dataApi.delete", "storage.get", "storage.buckets.list", "storage.buckets.create", "storage.buckets.delete", "storage.objects.list", "storage.objects.delete", "storage.objects.deleteByPrefix", "storage.objects.presign", "functions.list", "functions.get", "functions.update", "functions.delete", "functions.deploy", "credentials.list", "credentials.create", "credentials.revoke", "aiGateway.get", "logs.query", "logs.fields", "logs.fieldValues", "snapshots.list", "snapshots.create", "snapshots.update", "snapshots.delete", "snapshots.restore", "snapshots.getSchedule", "snapshots.setSchedule", "operations.list", "operations.get", "auth.get", "auth.create", "auth.disable", "auth.updateConfig", "auth.oauthProviders.list", "auth.oauthProviders.add", "auth.oauthProviders.update", "auth.oauthProviders.delete", "auth.trustedDomains.list", "auth.trustedDomains.add", "auth.trustedDomains.delete", "auth.users.create", "auth.users.delete", "auth.users.updateRole", "consumption.perProject", "consumption.perProjectV2", "consumption.perBranchV2", "apiKeys.list", "apiKeys.create", "apiKeys.revoke", "regions.list", "user.me", "user.organizations"];
|
|
4
4
|
export type NeonToolId = (typeof toolIds)[number];
|
|
5
5
|
export declare const isNeonToolId: (id: string) => id is NeonToolId;
|
|
6
6
|
export declare const unpublishedToolError: (id: string) => TypeError;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../../src/lib/ergonomic/ids.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../../src/lib/ergonomic/ids.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,mFAIhB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,eAAO,MAAM,OAAO,22EAuGV,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAElD,eAAO,MAAM,YAAY,GAAI,IAAI,MAAM,KAAG,EAAE,IAAI,UACJ,CAAC;AAS7C,eAAO,MAAM,oBAAoB,GAAI,IAAI,MAAM,KAAG,SAOjD,CAAC"}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
//#region src/lib/ergonomic/ids.ts
|
|
2
2
|
const hiddenToolIds = [
|
|
3
3
|
"operations.waitFor",
|
|
4
|
-
"branches.create",
|
|
5
|
-
"projects.create",
|
|
6
4
|
"postgres.roles.password",
|
|
7
5
|
"storage.objects.get"
|
|
8
6
|
];
|
|
9
7
|
const toolIds = [
|
|
10
8
|
"projects.list",
|
|
11
9
|
"projects.get",
|
|
10
|
+
"projects.create",
|
|
12
11
|
"projects.createAndConnect",
|
|
13
12
|
"projects.update",
|
|
14
13
|
"projects.delete",
|
|
@@ -23,7 +22,8 @@ const toolIds = [
|
|
|
23
22
|
"projects.members.removeRole",
|
|
24
23
|
"branches.list",
|
|
25
24
|
"branches.get",
|
|
26
|
-
"branches.
|
|
25
|
+
"branches.create",
|
|
26
|
+
"branches.createAndConnect",
|
|
27
27
|
"branches.update",
|
|
28
28
|
"branches.delete",
|
|
29
29
|
"branches.getDefault",
|
|
@@ -110,8 +110,6 @@ const toolIds = [
|
|
|
110
110
|
];
|
|
111
111
|
const isNeonToolId = (id) => toolIds.includes(id);
|
|
112
112
|
const hiddenToolHint = {
|
|
113
|
-
"projects.create": "Use \"projects.createAndConnect\", which attaches compute and returns a connection string.",
|
|
114
|
-
"branches.create": "Use \"branches.createWithCompute\", which attaches compute and returns a connection string.",
|
|
115
113
|
"operations.waitFor": "Write tools wait for readiness. operations.waitFor is not a tool.",
|
|
116
114
|
"postgres.roles.password": "Role passwords are not published as a tool.",
|
|
117
115
|
"storage.objects.get": "Object bytes are not published as a tool."
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
export declare const compactJsonSchema: (node: unknown) => unknown;
|
|
3
|
+
export interface McpStandardSchema {
|
|
4
|
+
"~standard": {
|
|
5
|
+
version: number;
|
|
6
|
+
vendor: string;
|
|
7
|
+
jsonSchema: {
|
|
8
|
+
input: () => Record<string, unknown>;
|
|
9
|
+
output: () => Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
validate: (value: unknown) => unknown;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export declare const toMcpInputSchema: (schema: z.ZodType) => McpStandardSchema;
|
|
15
|
+
//# sourceMappingURL=mcp-json-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-json-schema.d.ts","sourceRoot":"","sources":["../../src/lib/mcp-json-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAKzB,eAAO,MAAM,iBAAiB,GAAI,MAAM,OAAO,KAAG,OAOjD,CAAC;AAMF,MAAM,WAAW,iBAAiB;IACjC,WAAW,EAAE;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE;YACX,KAAK,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACrC,MAAM,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SACtC,CAAC;QACF,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;KACtC,CAAC;CACF;AAED,eAAO,MAAM,gBAAgB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,iBAiCpD,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
//#region src/lib/mcp-json-schema.ts
|
|
3
|
+
const isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
+
const compactJsonSchema = (node) => {
|
|
5
|
+
if (!isPlainObject(node)) return node;
|
|
6
|
+
const rest = { ...node };
|
|
7
|
+
delete rest.$schema;
|
|
8
|
+
return rest;
|
|
9
|
+
};
|
|
10
|
+
const isStandardValidate = (value) => typeof value === "function";
|
|
11
|
+
const toMcpInputSchema = (schema) => {
|
|
12
|
+
const json = compactJsonSchema(z.toJSONSchema(schema, { io: "input" }));
|
|
13
|
+
if (!isPlainObject(json)) throw new TypeError("MCP tool input schemas must be JSON Schema objects");
|
|
14
|
+
const standard = "~standard" in schema && isPlainObject(schema["~standard"]) ? schema["~standard"] : void 0;
|
|
15
|
+
const validate = standard === void 0 ? void 0 : standard.validate;
|
|
16
|
+
return { "~standard": {
|
|
17
|
+
version: 1,
|
|
18
|
+
vendor: "neon",
|
|
19
|
+
jsonSchema: {
|
|
20
|
+
input: () => json,
|
|
21
|
+
output: () => json
|
|
22
|
+
},
|
|
23
|
+
validate: (value) => {
|
|
24
|
+
if (isStandardValidate(validate)) return validate(value);
|
|
25
|
+
const parsed = schema.safeParse(value);
|
|
26
|
+
return parsed.success ? { value: parsed.data } : { issues: parsed.error.issues };
|
|
27
|
+
}
|
|
28
|
+
} };
|
|
29
|
+
};
|
|
30
|
+
//#endregion
|
|
31
|
+
export { compactJsonSchema, toMcpInputSchema };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { NeonTool } from "./operation.js";
|
|
2
|
+
export interface McpToolResult {
|
|
3
|
+
content: Array<{
|
|
4
|
+
type: "text";
|
|
5
|
+
text: string;
|
|
6
|
+
}>;
|
|
7
|
+
structuredContent: Record<string, unknown>;
|
|
8
|
+
isError?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface McpToolServer {
|
|
11
|
+
registerTool: object;
|
|
12
|
+
}
|
|
13
|
+
export declare const registerNeonToolsWithSchema: (server: McpToolServer, tools: Readonly<Record<string, NeonTool>>, inputSchema: (tool: NeonTool) => unknown) => void;
|
|
14
|
+
//# sourceMappingURL=mcp-register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-register.d.ts","sourceRoot":"","sources":["../../src/lib/mcp-register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC7B,YAAY,EAAE,MAAM,CAAC;CACrB;AA0FD,eAAO,MAAM,2BAA2B,GACvC,QAAQ,aAAa,EACrB,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,EACzC,aAAa,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO,KACtC,IAkBF,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//#region src/lib/mcp-register.ts
|
|
2
|
+
const errorMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
3
|
+
const isRecord = (value) => typeof value === "object" && value !== null;
|
|
4
|
+
const authInfoFrom = (context) => {
|
|
5
|
+
if (!isRecord(context)) return;
|
|
6
|
+
if (isRecord(context.http) && "authInfo" in context.http) return context.http.authInfo;
|
|
7
|
+
if ("authInfo" in context) return context.authInfo;
|
|
8
|
+
};
|
|
9
|
+
const bearerCredentialFromMcpContext = (context) => {
|
|
10
|
+
const authInfo = authInfoFrom(context);
|
|
11
|
+
if (authInfo === void 0) return;
|
|
12
|
+
if (!isRecord(authInfo) || typeof authInfo.token !== "string" || authInfo.token.length === 0) throw new TypeError("A Neon API key or OAuth access token is required");
|
|
13
|
+
return authInfo.token;
|
|
14
|
+
};
|
|
15
|
+
const signalFrom = (context) => {
|
|
16
|
+
if (!isRecord(context)) return;
|
|
17
|
+
if (context.signal instanceof AbortSignal) return context.signal;
|
|
18
|
+
if (isRecord(context.mcpReq) && context.mcpReq.signal instanceof AbortSignal) return context.mcpReq.signal;
|
|
19
|
+
};
|
|
20
|
+
const createToolHandler = (tool) => async (input, context) => {
|
|
21
|
+
try {
|
|
22
|
+
const apiKey = bearerCredentialFromMcpContext(context);
|
|
23
|
+
const structuredContent = { data: (await tool.execute(input, {
|
|
24
|
+
signal: signalFrom(context),
|
|
25
|
+
...apiKey === void 0 ? {} : { apiKey }
|
|
26
|
+
})).data };
|
|
27
|
+
return {
|
|
28
|
+
content: [{
|
|
29
|
+
type: "text",
|
|
30
|
+
text: JSON.stringify(structuredContent)
|
|
31
|
+
}],
|
|
32
|
+
structuredContent
|
|
33
|
+
};
|
|
34
|
+
} catch (error) {
|
|
35
|
+
const structuredContent = { error: { message: errorMessage(error) } };
|
|
36
|
+
return {
|
|
37
|
+
content: [{
|
|
38
|
+
type: "text",
|
|
39
|
+
text: JSON.stringify(structuredContent)
|
|
40
|
+
}],
|
|
41
|
+
structuredContent,
|
|
42
|
+
isError: true
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const registerNeonToolsWithSchema = (server, tools, inputSchema) => {
|
|
47
|
+
if (typeof server.registerTool !== "function") throw new TypeError("Expected an MCP server with registerTool().");
|
|
48
|
+
for (const tool of Object.values(tools)) Reflect.apply(server.registerTool, server, [
|
|
49
|
+
tool.id,
|
|
50
|
+
{
|
|
51
|
+
title: tool.title,
|
|
52
|
+
description: tool.description,
|
|
53
|
+
inputSchema: inputSchema(tool),
|
|
54
|
+
annotations: tool.annotations,
|
|
55
|
+
_meta: { "neon/requiresApproval": tool.requiresApproval }
|
|
56
|
+
},
|
|
57
|
+
createToolHandler(tool)
|
|
58
|
+
]);
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
export { registerNeonToolsWithSchema };
|
package/dist/mcp-v1.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { type McpToolResult, type McpToolServer } from "./lib/mcp-register.js";
|
|
2
|
+
import type { NeonTool } from "./lib/operation.js";
|
|
3
|
+
export type { McpToolResult, McpToolServer };
|
|
4
|
+
export declare const registerNeonTools: (server: McpToolServer, tools: Readonly<Record<string, NeonTool>>) => void;
|
|
3
5
|
//# sourceMappingURL=mcp-v1.d.ts.map
|
package/dist/mcp-v1.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-v1.d.ts","sourceRoot":"","sources":["../src/mcp-v1.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"mcp-v1.d.ts","sourceRoot":"","sources":["../src/mcp-v1.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,aAAa,EAElB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AAE7C,eAAO,MAAM,iBAAiB,GAC7B,QAAQ,aAAa,EACrB,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,KACvC,IAEF,CAAC"}
|
package/dist/mcp-v1.js
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { registerNeonToolsWithSchema } from "./lib/mcp-register.js";
|
|
2
|
+
//#region src/mcp-v1.ts
|
|
3
|
+
const registerNeonTools = (server, tools) => {
|
|
4
|
+
registerNeonToolsWithSchema(server, tools, (tool) => tool.inputSchema);
|
|
5
|
+
};
|
|
6
|
+
//#endregion
|
|
2
7
|
export { registerNeonTools };
|
package/dist/mcp.d.ts
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
|
+
import { compactJsonSchema, toMcpInputSchema } from "./lib/mcp-json-schema.js";
|
|
2
|
+
import { type McpToolResult, type McpToolServer } from "./lib/mcp-register.js";
|
|
1
3
|
import type { NeonTool } from "./lib/operation.js";
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
text: string;
|
|
6
|
-
}>;
|
|
7
|
-
structuredContent: Record<string, unknown>;
|
|
8
|
-
isError?: boolean;
|
|
9
|
-
}
|
|
10
|
-
export interface McpToolServer {
|
|
11
|
-
registerTool: object;
|
|
12
|
-
}
|
|
4
|
+
export type { McpStandardSchema } from "./lib/mcp-json-schema.js";
|
|
5
|
+
export type { McpToolResult, McpToolServer };
|
|
6
|
+
export { compactJsonSchema, toMcpInputSchema };
|
|
13
7
|
export declare const registerNeonTools: (server: McpToolServer, tools: Readonly<Record<string, NeonTool>>) => void;
|
|
14
8
|
//# sourceMappingURL=mcp.d.ts.map
|
package/dist/mcp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,aAAa,EAElB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;AAE/C,eAAO,MAAM,iBAAiB,GAC7B,QAAQ,aAAa,EACrB,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,KACvC,IAIF,CAAC"}
|
package/dist/mcp.js
CHANGED
|
@@ -1,60 +1,8 @@
|
|
|
1
|
+
import { registerNeonToolsWithSchema } from "./lib/mcp-register.js";
|
|
2
|
+
import { compactJsonSchema, toMcpInputSchema } from "./lib/mcp-json-schema.js";
|
|
1
3
|
//#region src/mcp.ts
|
|
2
|
-
const errorMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
3
|
-
const isRecord = (value) => typeof value === "object" && value !== null;
|
|
4
|
-
const authInfoFrom = (context) => {
|
|
5
|
-
if (!isRecord(context)) return;
|
|
6
|
-
if (isRecord(context.http) && "authInfo" in context.http) return context.http.authInfo;
|
|
7
|
-
if ("authInfo" in context) return context.authInfo;
|
|
8
|
-
};
|
|
9
|
-
const bearerCredentialFromMcpContext = (context) => {
|
|
10
|
-
const authInfo = authInfoFrom(context);
|
|
11
|
-
if (authInfo === void 0) return;
|
|
12
|
-
if (!isRecord(authInfo) || typeof authInfo.token !== "string" || authInfo.token.length === 0) throw new TypeError("A Neon API key or OAuth access token is required");
|
|
13
|
-
return authInfo.token;
|
|
14
|
-
};
|
|
15
|
-
const signalFrom = (context) => {
|
|
16
|
-
if (!isRecord(context)) return;
|
|
17
|
-
if (context.signal instanceof AbortSignal) return context.signal;
|
|
18
|
-
if (isRecord(context.mcpReq) && context.mcpReq.signal instanceof AbortSignal) return context.mcpReq.signal;
|
|
19
|
-
};
|
|
20
4
|
const registerNeonTools = (server, tools) => {
|
|
21
|
-
|
|
22
|
-
for (const tool of Object.values(tools)) Reflect.apply(server.registerTool, server, [
|
|
23
|
-
tool.id,
|
|
24
|
-
{
|
|
25
|
-
title: tool.title,
|
|
26
|
-
description: tool.description,
|
|
27
|
-
inputSchema: tool.inputSchema,
|
|
28
|
-
annotations: tool.annotations,
|
|
29
|
-
_meta: { "neon/requiresApproval": tool.requiresApproval }
|
|
30
|
-
},
|
|
31
|
-
async (input, context) => {
|
|
32
|
-
try {
|
|
33
|
-
const apiKey = bearerCredentialFromMcpContext(context);
|
|
34
|
-
const structuredContent = { data: (await tool.execute(input, {
|
|
35
|
-
signal: signalFrom(context),
|
|
36
|
-
...apiKey === void 0 ? {} : { apiKey }
|
|
37
|
-
})).data };
|
|
38
|
-
return {
|
|
39
|
-
content: [{
|
|
40
|
-
type: "text",
|
|
41
|
-
text: JSON.stringify(structuredContent)
|
|
42
|
-
}],
|
|
43
|
-
structuredContent
|
|
44
|
-
};
|
|
45
|
-
} catch (error) {
|
|
46
|
-
const structuredContent = { error: { message: errorMessage(error) } };
|
|
47
|
-
return {
|
|
48
|
-
content: [{
|
|
49
|
-
type: "text",
|
|
50
|
-
text: JSON.stringify(structuredContent)
|
|
51
|
-
}],
|
|
52
|
-
structuredContent,
|
|
53
|
-
isError: true
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
]);
|
|
5
|
+
registerNeonToolsWithSchema(server, tools, (tool) => toMcpInputSchema(tool.inputSchema));
|
|
58
6
|
};
|
|
59
7
|
//#endregion
|
|
60
|
-
export { registerNeonTools };
|
|
8
|
+
export { compactJsonSchema, registerNeonTools, toMcpInputSchema };
|