@noimosai/platform-mcp 0.1.3 → 0.1.5

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 (93) hide show
  1. package/README.md +17 -48
  2. package/bin/noimos-platform-mcp.mjs +4 -5
  3. package/dist/cli/cli.js +565 -0
  4. package/dist/cli/command-help.js +395 -0
  5. package/dist/cli/download.js +79 -0
  6. package/dist/cli/index.js +3 -0
  7. package/dist/cli/input-error.js +48 -0
  8. package/dist/cli/local-agents.js +199 -0
  9. package/dist/cli/mcp-supervisor.js +136 -0
  10. package/dist/cli/noimos-cli.js +72 -0
  11. package/dist/cli/project-archive.js +27 -0
  12. package/dist/cli/project-files.js +25 -0
  13. package/dist/cli/project-sync.js +265 -0
  14. package/dist/cli/setup-lock.js +1 -0
  15. package/dist/cli/setup.js +347 -0
  16. package/dist/cli/skills.js +142 -0
  17. package/dist/cli/team-harness-targets.js +337 -0
  18. package/dist/cli/team-harness.js +1562 -0
  19. package/dist/cli/team-resources.js +222 -0
  20. package/dist/cli/team-skills.js +457 -0
  21. package/dist/cli/update-bootstrap.js +437 -0
  22. package/dist/cli/update-release.js +212 -0
  23. package/dist/cli/version.js +1 -0
  24. package/dist/cli/wallet.js +85 -0
  25. package/dist/client/agent-run.js +1425 -0
  26. package/dist/client/browser.js +911 -0
  27. package/dist/client/distribution.js +2 -0
  28. package/dist/client/evm-wallet.js +214 -0
  29. package/dist/client/execution-context.js +14 -0
  30. package/dist/client/failure-recovery.js +128 -0
  31. package/dist/client/index.js +4 -225
  32. package/dist/client/local-input.js +33 -12
  33. package/dist/client/local-profile-lock.js +52 -0
  34. package/dist/client/local-profile.js +181 -0
  35. package/dist/client/local-projects.js +131 -0
  36. package/dist/client/local-setup.js +93 -0
  37. package/dist/client/realtime-voice.js +184 -0
  38. package/dist/client/tool-name-hints.js +48 -0
  39. package/dist/client/wallet-access.js +214 -0
  40. package/dist/mcp/agent-server.js +345 -0
  41. package/dist/mcp/context.js +86 -0
  42. package/dist/mcp/host-schema.js +76 -0
  43. package/dist/mcp/icon.js +1 -0
  44. package/dist/mcp/instructions.js +26 -0
  45. package/dist/mcp/local-projects.js +42 -0
  46. package/dist/mcp/local-upload.js +7 -13
  47. package/dist/mcp/noimos-runtime.js +18 -0
  48. package/dist/mcp/noimos-server.js +38 -0
  49. package/dist/mcp/operations.js +41 -0
  50. package/dist/mcp/parallel-result.js +17 -0
  51. package/dist/mcp/project-sync.js +105 -0
  52. package/dist/mcp/results-reply.js +15 -0
  53. package/dist/mcp/runtime.js +65 -11
  54. package/dist/mcp/server.js +382 -40
  55. package/dist/mcp/team-skill.js +63 -0
  56. package/dist/mcp/update-notice.js +75 -0
  57. package/dist/mcp/version.js +1 -0
  58. package/dist/schema/accountRequestMethods.js +1 -0
  59. package/dist/schema/boundedBody.js +30 -0
  60. package/dist/schema/cronValidator.js +150 -0
  61. package/dist/schema/platformApiKey.js +14 -0
  62. package/dist/schema/platformAppAuth.js +11 -0
  63. package/dist/schema/platformBillingConstants.js +4 -0
  64. package/dist/schema/platformCapabilityFamilies.js +293 -0
  65. package/dist/schema/platformConnectionCatalog.js +39 -0
  66. package/dist/schema/platformConnectionPolicy.js +33 -0
  67. package/dist/schema/platformCustomTools.js +148 -0
  68. package/dist/schema/platformEndUserApi.js +62 -0
  69. package/dist/schema/platformFunding.js +10 -0
  70. package/dist/schema/platformHttpConstraints.js +12 -0
  71. package/dist/schema/platformLocalSetup.js +25 -0
  72. package/dist/schema/platformMcpTools.js +7 -0
  73. package/dist/schema/platformMetaTools.js +63 -0
  74. package/dist/schema/platformMonitorSchedule.js +123 -0
  75. package/dist/schema/platformMonitors.js +159 -0
  76. package/dist/schema/platformOAuth.js +13 -0
  77. package/dist/schema/platformProjectPermissions.js +33 -0
  78. package/dist/schema/platformPublicExecution.js +202 -21
  79. package/dist/schema/platformRoutes.js +122 -0
  80. package/dist/schema/platformSkills.js +11 -0
  81. package/dist/schema/platformTeamSecretName.js +3 -0
  82. package/dist/schema/platformTeamSkillSlug.js +1 -0
  83. package/dist/schema/platformTeamSkills.js +302 -0
  84. package/dist/schema/platformToolAccess.js +62 -0
  85. package/dist/schema/platformTriggers.js +153 -0
  86. package/dist/schema/platformWorkflows.js +100 -0
  87. package/dist/schema/scheduleTimeZone.js +15 -0
  88. package/dist/schema/toolDiscovery.js +71 -0
  89. package/dist/schema/toolInputRepair.js +122 -0
  90. package/dist/schema/toolResultContext.js +51 -0
  91. package/dist/schema/untrustedContent.js +35 -0
  92. package/npm-shrinkwrap.json +73 -0
  93. package/package.json +5 -3
@@ -0,0 +1,222 @@
1
+ import { parseArgs } from "node:util";
2
+ import { PLATFORM_MONITOR_ID, platformCustomToolCreateSchema, platformCustomToolRestoreSchema, platformCustomToolUpdateSchema, platformJsonObjectSchema, platformMemberAccessUpdateSchema, platformMonitorCreateSchema, platformMonitorDestinationInputSchema, platformMonitorEventsQuerySchema, platformMonitorQuoteSchema, platformMonitorResumeSchema, platformTeamSkillRestoreSchema, platformTriggerCreateSchema, platformTriggerDestinationInputSchema, platformTriggerEventsQuerySchema, platformTriggerIdSchema, platformTriggerTypesQuerySchema, platformTriggerUpdateSchema } from "../client/index.js";
3
+ import { CliInputError, jsonOption } from "./input-error.js";
4
+ const OPTIONS = { "input-file": { type: "string" }, "expected-version": { type: "string" }, version: { type: "string" },
5
+ "idempotency-key": { type: "string" }, limit: { type: "string" }, tool: { type: "string" }, args: { type: "string" }, provider: { type: "string" },
6
+ interval: { type: "string" }, cron: { type: "string" }, "time-zone": { type: "string" }, name: { type: "string" }, "maximum-charge-micros-per-run": { type: "string" }, monitor: { type: "string" },
7
+ after: { type: "string" }, connection: { type: "string" }, "items-path": { type: "string" }, "maximum-charge-micros-per-poll": { type: "string" }, type: { type: "string" }, config: { type: "string" },
8
+ destinations: { type: "string" }, destination: { type: "string" }, "destination-id": { type: "string" }, enabled: { type: "string" }, app: { type: "string" }, query: { type: "string" },
9
+ offset: { type: "string" }, trigger: { type: "string" }, tools: { type: "string" }, all: { type: "boolean" } };
10
+ const COMMON = {
11
+ "custom-tools": { list: client => client.customTools(), get: name => client => client.customTool(name), versions: name => client => client.customToolVersions(name), delete: name => client => client.deleteCustomTool(name) },
12
+ "team-skills": { list: client => client.teamSkills(), get: slug => client => client.teamSkill(slug), versions: slug => client => client.teamSkillVersions(slug), delete: slug => client => client.deleteTeamSkill(slug) },
13
+ };
14
+ export const isTeamResource = (name) => Object.hasOwn(COMMON, name) || ["monitors", "triggers", "access"].includes(name);
15
+ function parsed(args, allowed) {
16
+ const { values, tokens } = parseArgs({ args: args.slice(2), tokens: true, allowPositionals: true, options: OPTIONS });
17
+ const names = tokens.flatMap(token => token.kind === "option" ? [token.name] : []);
18
+ const refused = names.find((name, index) => names.indexOf(name) !== index || !allowed.some(option => option === name));
19
+ if (refused)
20
+ throw new CliInputError(`${names.filter(name => name === refused).length > 1 ? "Duplicate" : "Invalid"} ${args[0]} ${args[1]} option --${refused}`);
21
+ const positionals = tokens.flatMap(token => token.kind === "positional" ? [token.value] : []);
22
+ return { values, name: positionals[0], rest: positionals.slice(1) };
23
+ }
24
+ const number = (value) => value === undefined ? undefined : Number(value);
25
+ const json = (name, value) => value === undefined ? undefined : jsonOption(name, value);
26
+ function positiveInteger(value, option) {
27
+ if (value === undefined || !/^[1-9]\d{0,14}$/.test(value))
28
+ throw new CliInputError(`--${option} needs a whole number from 1`);
29
+ return Number(value);
30
+ }
31
+ function named({ name, rest }) {
32
+ if (!name || rest.length)
33
+ throw new CliInputError("Provide one name");
34
+ return name;
35
+ }
36
+ function nothingNamed({ name }, args) {
37
+ if (name)
38
+ throw new CliInputError(`${args[0]} ${args[1]} takes no name`);
39
+ }
40
+ async function definitionOf({ values, rest }, readInput) {
41
+ const piped = rest.length === 1 && rest[0] === "-";
42
+ if ((rest.length && !piped) || piped === (values["input-file"] !== undefined))
43
+ throw new CliInputError("Pass the definition with - (stdin) or --input-file <path>");
44
+ return JSON.parse(await readInput(piped ? "-" : values["input-file"] ?? ""));
45
+ }
46
+ const objectOf = (value) => platformJsonObjectSchema.parse(value);
47
+ function monitorCommand(args, action) {
48
+ const target = ["tool", "args", "provider", "interval", "cron", "time-zone"];
49
+ const allowed = action === "create" ? [...target, "name", "maximum-charge-micros-per-run"] : action === "quote" ? target : action === "resume" ? ["maximum-charge-micros-per-run"]
50
+ : action === "events" ? ["monitor", "after", "limit"] : action === "destination-add" ? ["destination"] : action === "destination-remove" ? ["destination-id"] : [];
51
+ const input = parsed(args, allowed), { values } = input;
52
+ const id = () => {
53
+ if (!input.name || input.rest.length || !PLATFORM_MONITOR_ID.test(input.name))
54
+ throw new CliInputError("Provide a valid monitor ID");
55
+ return input.name;
56
+ };
57
+ const targetInput = () => ({ tool: values.tool, arguments: json("--args", values.args), provider: values.provider, interval: values.interval, cron: values.cron, timeZone: values["time-zone"] });
58
+ const accepted = number(values["maximum-charge-micros-per-run"]);
59
+ switch (action) {
60
+ case "list":
61
+ nothingNamed(input, args);
62
+ return client => client.monitors();
63
+ case "popular":
64
+ nothingNamed(input, args);
65
+ return client => client.popularMonitors();
66
+ case "tools":
67
+ nothingNamed(input, args);
68
+ return client => client.monitorableTools();
69
+ case "delete": {
70
+ const monitor = id();
71
+ return client => client.deleteMonitor(monitor);
72
+ }
73
+ case "quote": {
74
+ nothingNamed(input, args);
75
+ const body = platformMonitorQuoteSchema.parse(targetInput());
76
+ return client => client.quoteMonitor(body);
77
+ }
78
+ case "create": {
79
+ nothingNamed(input, args);
80
+ const body = platformMonitorCreateSchema.parse({ ...targetInput(), name: values.name, maximumChargeMicrosPerRun: accepted });
81
+ return client => client.createMonitor(body);
82
+ }
83
+ case "resume": {
84
+ const monitor = id(), body = platformMonitorResumeSchema.parse({ maximumChargeMicrosPerRun: accepted });
85
+ return client => client.resumeMonitor(monitor, body);
86
+ }
87
+ case "events": {
88
+ nothingNamed(input, args);
89
+ const query = { monitorId: values.monitor, after: values.after, limit: number(values.limit) };
90
+ platformMonitorEventsQuerySchema.parse({ after: query.after, limit: query.limit });
91
+ if (query.monitorId !== undefined && !PLATFORM_MONITOR_ID.test(query.monitorId))
92
+ throw new CliInputError("Provide a valid monitor ID");
93
+ return client => client.monitorEvents(query);
94
+ }
95
+ case "destination-add": {
96
+ const monitor = id(), body = platformMonitorDestinationInputSchema.parse(json("--destination", values.destination));
97
+ return client => client.addMonitorDestination(monitor, body);
98
+ }
99
+ case "destination-remove": {
100
+ const monitor = id(), destination = values["destination-id"];
101
+ if (!destination)
102
+ throw new CliInputError("Provide --destination-id as relvo monitors list shows it");
103
+ return client => client.removeMonitorDestination(monitor, destination);
104
+ }
105
+ default: throw new CliInputError("Invalid monitors command");
106
+ }
107
+ }
108
+ function triggerCommand(args, action) {
109
+ const allowed = action === "create" ? ["connection", "tool", "args", "interval", "items-path", "maximum-charge-micros-per-poll", "type", "config", "destinations", "name"]
110
+ : action === "update" ? ["enabled", "name"] : action === "types" ? ["app", "connection", "query", "offset", "limit"] : action === "events" ? ["trigger", "after", "limit"]
111
+ : action === "destination-add" ? ["destination"] : action === "destination-remove" ? ["destination-id"] : [];
112
+ const input = parsed(args, allowed), { values } = input;
113
+ const id = () => {
114
+ if (!input.name || input.rest.length || !platformTriggerIdSchema.safeParse(input.name).success)
115
+ throw new CliInputError("Provide a valid trigger ID");
116
+ return input.name;
117
+ };
118
+ switch (action) {
119
+ case "list":
120
+ nothingNamed(input, args);
121
+ return client => client.triggers();
122
+ case "types": {
123
+ nothingNamed(input, args);
124
+ const query = platformTriggerTypesQuerySchema.parse({ app: values.app, connectionId: values.connection, query: values.query, offset: number(values.offset), limit: number(values.limit) });
125
+ return client => client.triggerTypes(query);
126
+ }
127
+ case "delete": {
128
+ const trigger = id();
129
+ return client => client.deleteTrigger(trigger);
130
+ }
131
+ case "update": {
132
+ if (values.enabled !== undefined && values.enabled !== "true" && values.enabled !== "false")
133
+ throw new CliInputError("--enabled is true or false");
134
+ const trigger = id(), body = platformTriggerUpdateSchema.parse({ enabled: values.enabled === undefined ? undefined : values.enabled === "true", name: values.name });
135
+ return client => client.updateTrigger(trigger, body);
136
+ }
137
+ case "create": {
138
+ nothingNamed(input, args);
139
+ const fields = { kind: values.tool !== undefined ? "poll" : "webhook", connectionId: values.connection, name: values.name, destinations: json("--destinations", values.destinations),
140
+ tool: values.tool, arguments: json("--args", values.args), interval: values.interval, itemsPath: values["items-path"],
141
+ maximumChargeMicrosPerPoll: number(values["maximum-charge-micros-per-poll"]), type: values.type, config: json("--config", values.config) };
142
+ const body = platformTriggerCreateSchema.parse(Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== undefined)));
143
+ return client => client.createTrigger(body);
144
+ }
145
+ case "events": {
146
+ nothingNamed(input, args);
147
+ const query = { triggerId: values.trigger, after: values.after, limit: number(values.limit) };
148
+ platformTriggerEventsQuerySchema.parse({ after: query.after, limit: query.limit });
149
+ if (query.triggerId !== undefined && !platformTriggerIdSchema.safeParse(query.triggerId).success)
150
+ throw new CliInputError("Provide a valid trigger ID");
151
+ return client => client.triggerEvents(query);
152
+ }
153
+ case "destination-add": {
154
+ const trigger = id(), body = platformTriggerDestinationInputSchema.parse(json("--destination", values.destination));
155
+ return client => client.addTriggerDestination(trigger, body);
156
+ }
157
+ case "destination-remove": {
158
+ const trigger = id(), destination = values["destination-id"];
159
+ if (!destination)
160
+ throw new CliInputError("Provide --destination-id as relvo triggers list shows it");
161
+ return client => client.removeTriggerDestination(trigger, destination);
162
+ }
163
+ default: throw new CliInputError("Invalid triggers command");
164
+ }
165
+ }
166
+ function accessCommand(args, action) {
167
+ if (action === "list") {
168
+ nothingNamed(parsed(args, []), args);
169
+ return client => client.access();
170
+ }
171
+ if (action !== "set")
172
+ throw new CliInputError("Invalid access command");
173
+ const input = parsed(args, ["tools", "all"]), { values } = input;
174
+ if (!input.name || input.rest.length || !/^[A-Za-z0-9-]{1,128}$/.test(input.name))
175
+ throw new CliInputError("Provide one member ID as relvo access list shows it");
176
+ if (Boolean(values.all) === (values.tools !== undefined))
177
+ throw new CliInputError("Pass --tools '<json array>' or --all");
178
+ const member = input.name, body = platformMemberAccessUpdateSchema.parse({ toolAccess: values.all ? null : jsonOption("--tools", values.tools ?? "") });
179
+ return client => client.updateMemberAccess(member, body);
180
+ }
181
+ export async function teamResourceCommand(args, readInput) {
182
+ const [resource, action = ""] = args;
183
+ if (resource === "monitors")
184
+ return monitorCommand(args, action);
185
+ if (resource === "triggers")
186
+ return triggerCommand(args, action);
187
+ if (resource === "access")
188
+ return accessCommand(args, action);
189
+ const common = COMMON[resource];
190
+ if (!common)
191
+ throw new CliInputError(`Invalid ${resource} command`);
192
+ if (action === "list") {
193
+ nothingNamed(parsed(args, []), args);
194
+ return common.list;
195
+ }
196
+ if (action === "get" || action === "versions" || action === "delete")
197
+ return common[action](named(parsed(args, [])));
198
+ if (action === "restore") {
199
+ const input = parsed(args, ["version", "expected-version"]), name = named(input);
200
+ const versions = { version: positiveInteger(input.values.version, "version"), expectedVersion: positiveInteger(input.values["expected-version"], "expected-version") };
201
+ if (resource === "custom-tools") {
202
+ const body = platformCustomToolRestoreSchema.parse(versions);
203
+ return client => client.restoreCustomTool(name, body);
204
+ }
205
+ const body = platformTeamSkillRestoreSchema.parse(versions);
206
+ return client => client.restoreTeamSkill(name, body);
207
+ }
208
+ if ((action === "create" || action === "update") && resource !== "team-skills") {
209
+ const input = parsed(args, action === "create" ? ["input-file"] : ["input-file", "expected-version"]);
210
+ if (!input.name)
211
+ throw new CliInputError("Provide one name");
212
+ const name = input.name, definition = objectOf(await definitionOf(input, readInput));
213
+ if (action === "create") {
214
+ const body = platformCustomToolCreateSchema.parse({ ...definition, slug: name });
215
+ return client => client.createCustomTool(body);
216
+ }
217
+ const expectedVersion = positiveInteger(input.values["expected-version"], "expected-version");
218
+ const body = platformCustomToolUpdateSchema.parse({ ...definition, expectedVersion });
219
+ return client => client.updateCustomTool(name, body);
220
+ }
221
+ throw new CliInputError(resource === "team-skills" ? "Invalid team-skills command. relvo team-skills push <file or folder> shares or updates one" : `Invalid ${resource} command`);
222
+ }