@init-computer/mcp 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.
Files changed (2) hide show
  1. package/bin/init-mcp.js +201 -0
  2. package/package.json +16 -0
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env node
2
+ import readline from "node:readline";
3
+ import { InitApiError, createClient } from "../../sdk/dist/index.js";
4
+
5
+ const client = createClient({
6
+ apiKey: process.env.INIT_API_KEY,
7
+ baseUrl: process.env.INIT_API_BASE_URL,
8
+ });
9
+
10
+ const tools = [
11
+ {
12
+ name: "init_generate",
13
+ description: "Create or edit an Init API resource from a natural language prompt.",
14
+ inputSchema: objectSchema({
15
+ prompt: stringSchema("API to generate or edit."),
16
+ resource_id: optionalStringSchema("Existing resource id when editing."),
17
+ directories: arraySchema("Directory names to attach if they already exist."),
18
+ }, ["prompt"]),
19
+ handler: (args) => client.generate(args),
20
+ },
21
+ {
22
+ name: "init_generate_project",
23
+ description: "Create an Init project and a cohesive suite of one to seven generated endpoints.",
24
+ inputSchema: objectSchema({
25
+ prompt: stringSchema("Project and endpoint suite to generate."),
26
+ name: optionalStringSchema("Optional project name."),
27
+ description: optionalStringSchema("Optional project description."),
28
+ }, ["prompt"]),
29
+ handler: (args) => client.project.generate(args),
30
+ },
31
+ {
32
+ name: "init_edit_project",
33
+ description: "Add endpoints or create new versions of endpoints in an Init project.",
34
+ inputSchema: objectSchema({ project_id: stringSchema("Project id."), prompt: stringSchema("Project change request.") }, ["project_id", "prompt"]),
35
+ handler: ({ project_id, prompt }) => client.project.edit(project_id, { prompt }),
36
+ },
37
+ {
38
+ name: "init_run",
39
+ description: "Call a generated Init API route.",
40
+ inputSchema: objectSchema({
41
+ route: stringSchema("Route id, /vN/route path, or full URL."),
42
+ version: numberSchema("Version number when route is a bare id."),
43
+ input: freeObjectSchema("Request body to send to the generated endpoint."),
44
+ requestFormat: stringSchema("json or multipart/form-data."),
45
+ }, ["route"]),
46
+ handler: ({ route, version, input, requestFormat }) => client.run(route, input || {}, { version, requestFormat }),
47
+ },
48
+ {
49
+ name: "init_list_resources",
50
+ description: "List generated Init API resources owned by the API key user.",
51
+ inputSchema: freeObjectSchema("Optional resource filters."),
52
+ handler: (args) => client.resource.list(args || {}),
53
+ },
54
+ {
55
+ name: "init_get_resource",
56
+ description: "Get full details for one generated resource.",
57
+ inputSchema: objectSchema({ id: stringSchema("Resource id.") }, ["id"]),
58
+ handler: ({ id }) => client.resource.get(id),
59
+ },
60
+ {
61
+ name: "init_list_directories",
62
+ description: "List flat Init directories.",
63
+ inputSchema: freeObjectSchema("Optional directory filters."),
64
+ handler: (args) => client.directory.list(args || {}),
65
+ },
66
+ {
67
+ name: "init_list_daemons",
68
+ description: "List Init daemon workflows.",
69
+ inputSchema: freeObjectSchema("Optional daemon filters."),
70
+ handler: (args) => client.daemon.list(args || {}),
71
+ },
72
+ {
73
+ name: "init_create_daemon",
74
+ description: "Create a daemon for an existing Init resource/version.",
75
+ inputSchema: objectSchema({
76
+ resource_id: stringSchema("Resource id."),
77
+ version_id: stringSchema("Version id."),
78
+ input: freeObjectSchema("Daemon input body."),
79
+ interval_seconds: numberSchema("Interval in seconds."),
80
+ max_runs: numberSchema("Optional max run count."),
81
+ description: stringSchema("Optional daemon description."),
82
+ schedule: stringSchema("Schedule type or label."),
83
+ }, ["resource_id", "version_id", "input", "interval_seconds"]),
84
+ handler: (args) => client.daemon.create(args),
85
+ },
86
+ {
87
+ name: "init_run_daemon",
88
+ description: "Run a daemon once immediately.",
89
+ inputSchema: objectSchema({ id: stringSchema("Daemon id.") }, ["id"]),
90
+ handler: ({ id }) => client.daemon.run(id),
91
+ },
92
+ {
93
+ name: "init_list_packages",
94
+ description: "List package catalog entries and packages enabled for the user.",
95
+ inputSchema: freeObjectSchema("Optional package filters."),
96
+ handler: (args) => client.pkg.list(args || {}),
97
+ },
98
+ ];
99
+
100
+ const rl = readline.createInterface({
101
+ input: process.stdin,
102
+ output: process.stdout,
103
+ terminal: false,
104
+ });
105
+
106
+ rl.on("line", async (line) => {
107
+ if (!line.trim()) return;
108
+ let request;
109
+ try {
110
+ request = JSON.parse(line);
111
+ } catch (error) {
112
+ send({ jsonrpc: "2.0", id: null, error: { code: -32700, message: "Parse error" } });
113
+ return;
114
+ }
115
+ try {
116
+ const result = await handle(request);
117
+ if (request.id !== undefined) send({ jsonrpc: "2.0", id: request.id, result });
118
+ } catch (error) {
119
+ const message = error instanceof Error ? error.message : String(error);
120
+ send({
121
+ jsonrpc: "2.0",
122
+ id: request.id ?? null,
123
+ error: {
124
+ code: error instanceof InitApiError ? -32001 : -32603,
125
+ message,
126
+ data: error instanceof InitApiError ? { status: error.status, details: error.details } : undefined,
127
+ },
128
+ });
129
+ }
130
+ });
131
+
132
+ async function handle(request) {
133
+ switch (request.method) {
134
+ case "initialize":
135
+ return {
136
+ protocolVersion: "2024-11-05",
137
+ capabilities: { tools: {} },
138
+ serverInfo: { name: "init-mcp", version: "0.1.0" },
139
+ };
140
+ case "tools/list":
141
+ return { tools: tools.map(({ handler, ...tool }) => tool) };
142
+ case "tools/call": {
143
+ const name = request.params?.name;
144
+ const tool = tools.find((candidate) => candidate.name === name);
145
+ if (!tool) {
146
+ throw new Error(`Unknown tool: ${name}`);
147
+ }
148
+ const output = await tool.handler(request.params?.arguments || {});
149
+ return {
150
+ content: [
151
+ {
152
+ type: "text",
153
+ text: JSON.stringify(output, null, 2),
154
+ },
155
+ ],
156
+ };
157
+ }
158
+ case "ping":
159
+ return {};
160
+ default:
161
+ throw new Error(`Unsupported MCP method: ${request.method}`);
162
+ }
163
+ }
164
+
165
+ function send(message) {
166
+ process.stdout.write(`${JSON.stringify(message)}\n`);
167
+ }
168
+
169
+ function objectSchema(properties, required = []) {
170
+ return {
171
+ type: "object",
172
+ additionalProperties: false,
173
+ properties,
174
+ required,
175
+ };
176
+ }
177
+
178
+ function freeObjectSchema(description) {
179
+ return {
180
+ type: "object",
181
+ description,
182
+ additionalProperties: true,
183
+ properties: {},
184
+ };
185
+ }
186
+
187
+ function stringSchema(description) {
188
+ return { type: "string", description };
189
+ }
190
+
191
+ function optionalStringSchema(description) {
192
+ return { type: "string", description };
193
+ }
194
+
195
+ function numberSchema(description) {
196
+ return { type: "number", description };
197
+ }
198
+
199
+ function arraySchema(description) {
200
+ return { type: "array", description, items: { type: "string" } };
201
+ }
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@init-computer/mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for Init generated backend APIs.",
5
+ "type": "module",
6
+ "bin": {
7
+ "init-mcp": "./bin/init-mcp.js"
8
+ },
9
+ "dependencies": {
10
+ "@init-computer/sdk": "^0.1.3"
11
+ },
12
+ "engines": {
13
+ "node": ">=18"
14
+ },
15
+ "license": "UNLICENSED"
16
+ }