@zackbart/connecta 0.10.1 → 0.10.2

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 (69) hide show
  1. package/AGENTS.md +113 -0
  2. package/CHANGELOG.md +51 -0
  3. package/README.md +53 -9
  4. package/bin/connecta.mjs +272 -0
  5. package/dist/catalog-service.d.ts +39 -1
  6. package/dist/catalog-service.d.ts.map +1 -1
  7. package/dist/catalog-service.js +133 -11
  8. package/dist/catalog-service.js.map +1 -1
  9. package/dist/catalog.d.ts +17 -0
  10. package/dist/catalog.d.ts.map +1 -1
  11. package/dist/catalog.js +113 -13
  12. package/dist/catalog.js.map +1 -1
  13. package/dist/execute.d.ts +45 -1
  14. package/dist/execute.d.ts.map +1 -1
  15. package/dist/execute.js +265 -68
  16. package/dist/execute.js.map +1 -1
  17. package/dist/invocation.d.ts.map +1 -1
  18. package/dist/invocation.js +1 -5
  19. package/dist/invocation.js.map +1 -1
  20. package/dist/meta-tools.d.ts +1 -0
  21. package/dist/meta-tools.d.ts.map +1 -1
  22. package/dist/meta-tools.js +410 -12
  23. package/dist/meta-tools.js.map +1 -1
  24. package/dist/skills.d.ts +1 -1
  25. package/dist/skills.d.ts.map +1 -1
  26. package/dist/skills.js +1 -1
  27. package/dist/tool-safety.d.ts +10 -0
  28. package/dist/tool-safety.d.ts.map +1 -0
  29. package/dist/tool-safety.js +12 -0
  30. package/dist/tool-safety.js.map +1 -0
  31. package/dist/version.d.ts +1 -1
  32. package/dist/version.js +1 -1
  33. package/documentation/architecture.md +7 -0
  34. package/documentation/auth.md +58 -0
  35. package/documentation/call-admission.md +7 -0
  36. package/documentation/code-first-exploration.md +292 -0
  37. package/documentation/code-mode.md +697 -0
  38. package/documentation/connector-guides.md +7 -0
  39. package/documentation/connectors.md +63 -0
  40. package/documentation/mcp-2026-07-28.md +46 -0
  41. package/documentation/meta-tools.md +167 -0
  42. package/documentation/operations.md +7 -0
  43. package/documentation/operator-ui.md +7 -0
  44. package/documentation/request-admission.md +7 -0
  45. package/documentation/storage-and-credentials.md +54 -0
  46. package/ethos.md +132 -0
  47. package/examples/node/README.md +53 -0
  48. package/examples/node/src/index.ts +73 -0
  49. package/examples/worker/README.md +160 -0
  50. package/examples/worker/src/cloudflare-kv.ts +43 -0
  51. package/examples/worker/src/d1-activity-row.ts +100 -0
  52. package/examples/worker/src/d1-activity.ts +144 -0
  53. package/examples/worker/src/index.ts +136 -0
  54. package/examples/worker/wrangler.jsonc +26 -0
  55. package/package.json +11 -1
  56. package/src/catalog-service.ts +177 -15
  57. package/src/catalog.ts +143 -12
  58. package/src/execute.ts +372 -96
  59. package/src/invocation.ts +1 -8
  60. package/src/meta-tools.ts +504 -11
  61. package/src/skills.ts +1 -1
  62. package/src/tool-safety.ts +15 -0
  63. package/src/version.ts +1 -1
  64. package/templates/node/.env.example +5 -0
  65. package/templates/node/AGENTS.md +19 -0
  66. package/templates/node/README.md +33 -0
  67. package/templates/node/package.json +23 -0
  68. package/templates/node/src/index.ts +43 -0
  69. package/templates/node/tsconfig.json +12 -0
package/AGENTS.md ADDED
@@ -0,0 +1,113 @@
1
+ # Working on connecta
2
+
3
+ This is the canonical instruction file for coding agents. `CLAUDE.md` is a
4
+ symlink to this file so every agent works from the same conventions.
5
+
6
+ A single MCP endpoint aggregating downstream connectors (remote MCP servers and
7
+ plain HTTP APIs) behind a small fixed set of meta-tools. A deployment with an
8
+ executor serves seven, `execute_code` among them, and agents reach connectors by
9
+ writing JavaScript against it; one without an executor serves the nine classic
10
+ tools. One fetch-native core, running on both Node and Cloudflare Workers.
11
+
12
+ - **[`ethos.md`](./ethos.md) is the constitution.** It states what connecta is
13
+ and isn't, and its decisions table carries a verdict for every shape already
14
+ considered — refused, removed, provisional, or gated. Check the table before
15
+ designing or building anything: a `refused` row is a "no" with the reason
16
+ attached, and a `removed` row (toolkits
17
+ [#178](https://github.com/zackbart/connecta/issues/178), proactive credential
18
+ liveness [#179](https://github.com/zackbart/connecta/issues/179)) records a
19
+ surface that no longer exists — do not reintroduce it without a new decision.
20
+ - There is no TODO.md — the roadmap lives in
21
+ [GitHub issues](https://github.com/zackbart/connecta/issues). When you find
22
+ TODO items (in code comments, docs, or conversation), don't accumulate them
23
+ in a file: turn each one into a GitHub issue that clearly defines what to do
24
+ — motivation, behavioral requirements, and acceptance criteria — without
25
+ prescribing the implementation.
26
+
27
+ ## Verification
28
+
29
+ `npm run check` must pass before you claim anything is done — `check:docs` →
30
+ `check:operator-ui` → `check:lint` → `check:unused` → `typecheck` → `test`
31
+ (both vitest projects) → `build` → `check:examples`. It is also the `prepack`
32
+ hook. `npm run release:check` adds `check:security` and `check:package` and is
33
+ what CI runs on publish; use it when touching packaging, dependencies, or
34
+ exports.
35
+
36
+ ## The map
37
+
38
+ - [`ethos.md`](./ethos.md) — what connecta is, what it refuses to be, the
39
+ decisions table, and the invariants every change must preserve. Check it
40
+ before building something new; "we already decided not to" is a real answer
41
+ there, and its removed/provisional verdicts override anything staler.
42
+ - [`documentation/`](./documentation/) — per-subsystem guides for agents
43
+ working on the repo. **Currently stubs**: the old manual (`docs/`) was
44
+ retired in the phase-1 docs restructure and each guide is being rewritten as
45
+ the ideas settle. Until a guide is filled in, the subsystem's prior manual
46
+ text lives in git history (`docs/<name>.md`) — consult it there when you need
47
+ the old rationale, but treat `ethos.md` as the authority where they disagree.
48
+ - [`README.md`](./README.md) — the human-facing overview.
49
+ - [`templates/node/`](./templates/node/) — the one standalone Node deployment
50
+ shape copied by `connecta init`. Keep it small and prescribed; examples may
51
+ demonstrate alternatives, but they must not become competing scaffolds.
52
+
53
+ **Read `ethos.md` and the subsystem's guide (or its git-history predecessor)
54
+ before changing a subsystem.**
55
+
56
+ ## Deployment setup
57
+
58
+ `connecta init [directory]` is the golden path. It copies `templates/node/`,
59
+ pins the generated deployment to the CLI package's exact version, restores the
60
+ template `.gitignore`, and refuses to merge into an existing path.
61
+ `connecta doctor` verifies a running deployment's health, executor, and exact
62
+ seven-tool surface. Setup changes must keep the root README, template, Docker
63
+ example, and `scripts/check-package.mjs` smoke aligned; do not add a second
64
+ initializer or another “recommended” project shape.
65
+
66
+ ## Where new code goes
67
+
68
+ Two boundaries CI enforces that are not obvious from reading a file:
69
+
70
+ - **Import-graph purity.** Nothing reachable from `src/index.ts` may import a
71
+ `node:` builtin — the core is Web-API only so it runs unchanged on Workers.
72
+ `src/node.ts`, `src/storage/file.ts`, and the QuickJS process-pool entry
73
+ (`src/executors/quickjs.ts` + child) are the Node-touching paths and must stay
74
+ unreachable from the root entry. `test/purity.test.ts` walks the import graph
75
+ and fails otherwise. Need a Node API? It goes behind an explicit Node-only
76
+ subpath (`/node` or `/quickjs`), never the root.
77
+ - **The published surface.** Platform-specific storage adapters live in
78
+ `examples/`, not the package. `@clerk/backend` and `quickjs-emscripten` are
79
+ optional peers behind the `./auth/clerk` and `./quickjs` subpaths and must
80
+ never become dependencies or install with core. Enforced by
81
+ `test/package-surface.test.ts` and `scripts/check-package.mjs`. Anything
82
+ heavyweight or platform-bound gets a subpath and an optional peer.
83
+
84
+ ## Where new tests go
85
+
86
+ Suites live in `test/` and run as two vitest projects (`vitest.config.ts`).
87
+ Every `*.test.ts` belongs to exactly one explicit list: runtime-portable suites
88
+ in `WORKERS_SUITES`, Node-bound suites in `NODE_ONLY_SUITES` with a reason. The
89
+ `node` project runs both lists; the `workers` project re-runs the portable list
90
+ inside workerd. `test/suite-partition.test.ts` walks the directory and fails on
91
+ an unclassified, double-classified, stale, or reasonless entry. New behavior
92
+ also gets a row in the test map in
93
+ [`documentation/operations.md`](./documentation/operations.md) once that guide
94
+ is rewritten; until then the row waits with the guide.
95
+
96
+ ## Conventions
97
+
98
+ - **Static analysis.** `npm run check:lint` runs Oxlint's correctness category
99
+ only; it does not enforce style. `npm run check:unused` runs Knip's
100
+ unused-export and dependency gate. Keep both clean, and prefer removing dead
101
+ declarations over suppressing a finding.
102
+ - **Style.** There is no formatter. Match the surrounding code. The docs voice
103
+ is precise, occasionally wry, and always explains *why* — don't flatten it
104
+ into boilerplate.
105
+ - **Commits.** Imperative summary naming the behavior change, with issue refs in
106
+ parens: `Normalize maxResultBytes at every intake point (#32) (#39)`.
107
+ - **CHANGELOG.** Each release opens with a narrative paragraph — what this
108
+ release is, what breaks, what a deployment can ignore — then
109
+ `### Added` / `### Changed` / `### Fixed`.
110
+ - **Releases.** `npm run release:check`, tag `v<version>` matching
111
+ `package.json` exactly (the publish workflow verifies this and fails
112
+ otherwise), and publishing fires on GitHub **Release publication**, not on the
113
+ tag push.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,57 @@
2
2
 
3
3
  All notable changes to this package are documented here.
4
4
 
5
+ ## 0.10.2 — 2026-07-30
6
+
7
+ A prescribed deployment path for agents and operators. `connecta init` now
8
+ creates one small, reviewable Node project with exact dependencies and
9
+ auto-discoverable conventions; `connecta doctor` proves the running endpoint is
10
+ healthy, advertises the intended seven tools, and can actually execute a
11
+ harmless QuickJS program. The initializer never merges into an existing path,
12
+ and it stages the complete project before an atomic rename so an interrupted
13
+ setup leaves nothing half-created. **Existing deployments are unchanged.** The
14
+ new template refuses to start without an explicit bearer token, while the
15
+ repository Docker example now selects the same code-first surface by default.
16
+
17
+ ### Added
18
+
19
+ - **One command to create the prescribed deployment.**
20
+ `npx @zackbart/connecta init <directory>` writes only the deployment config,
21
+ exact package manifest, TypeScript config, environment example, ignore rules,
22
+ README, and canonical `AGENTS.md` with `CLAUDE.md` pointing to it. The command
23
+ refuses every existing destination and pins the generated project to the
24
+ initializer's exact Connecta version.
25
+ - **A live deployment doctor.** `CONNECTA_TOKEN=… connecta doctor` checks
26
+ `/health`, requires the exact seven-tool code-first surface, and runs
27
+ `async () => 42` through `execute_code`. Requests are bounded to ten seconds,
28
+ bearer tokens are accepted only from the environment, and remote plaintext
29
+ HTTP is refused.
30
+ - **Artifact-level setup qualification.** The package smoke now installs the
31
+ packed tarball, initializes a deployment, checks overwrite refusal, installs
32
+ and typechecks the generated project, verifies tokenless startup fails,
33
+ starts it with auth, and runs the live doctor through QuickJS.
34
+
35
+ ### Changed
36
+
37
+ - **Agent instructions have one source of truth.** `AGENTS.md` is canonical in
38
+ the package repository and generated deployments; `CLAUDE.md` is a symlink
39
+ where the filesystem supports it.
40
+ - **The setup material ships with the package.** The standalone template,
41
+ agent-facing documentation, ethos, and usable Node and Worker examples are
42
+ available beside the installed package. Docker remains explicitly
43
+ repository-only because its reproducible build consumes repository inputs.
44
+ - **The Docker example is code-first by default.** Its entrypoint configures the
45
+ bounded QuickJS executor instead of leaving operators to infer and add it.
46
+
47
+ ### Fixed
48
+
49
+ - **The prescribed Node deployment no longer has a known fallback secret.**
50
+ Both the generated template and repository example refuse startup when
51
+ `CONNECTA_TOKEN` is absent.
52
+ - **Failed initialization no longer strands a partial destination.** Work is
53
+ assembled in a uniquely named sibling directory, cleaned on failure, and
54
+ renamed into place only when complete.
55
+
5
56
  ## 0.10.1 — 2026-07-30
6
57
 
7
58
  An inbound-auth escape hatch for MCP clients whose OAuth implementations do not
package/README.md CHANGED
@@ -42,15 +42,59 @@ flowchart LR
42
42
 
43
43
  ## Start here
44
44
 
45
- - [Node example](./examples/node/)
46
- - [Docker example](./examples/docker/)
47
- - [Cloudflare Worker example](./examples/worker/)
48
- - [Documentation](./documentation/)
49
-
50
- Configuring a sandbox — a Dynamic Worker on Cloudflare, QuickJS on Node — is
51
- what selects the code-first surface, and it is the assumed posture. A
52
- deployment without one keeps the earlier nine-tool, call-by-call interface,
53
- which stays supported.
45
+ Create the prescribed Node deployment:
46
+
47
+ ```sh
48
+ npx @zackbart/connecta init my-connecta
49
+ cd my-connecta
50
+ npm install
51
+ CONNECTA_TOKEN=dev-token npm start
52
+ ```
53
+
54
+ Point an MCP client at `http://localhost:8787/mcp` with
55
+ `Authorization: Bearer dev-token`. The generated project is deliberately small:
56
+
57
+ ```text
58
+ my-connecta/
59
+ ├── src/index.ts # connectors, auth, storage, public URL
60
+ ├── package.json # exact Connecta and QuickJS versions
61
+ ├── tsconfig.json
62
+ ├── .env.example
63
+ ├── .gitignore
64
+ ├── AGENTS.md
65
+ ├── CLAUDE.md -> AGENTS.md
66
+ └── README.md
67
+ ```
68
+
69
+ For an agent setting this up, the contract is:
70
+
71
+ 1. Edit `src/index.ts`; do not copy Connecta internals into the deployment.
72
+ 2. Keep `executor: quickJsExecutor()` for the prescribed seven-tool surface.
73
+ 3. Keep secrets in environment variables or a secret store, never source.
74
+ 4. Add code only for deliberate `api()` connectors.
75
+ 5. Run `npm run typecheck`, start the server, and run
76
+ `CONNECTA_TOKEN=... npm run doctor`. Doctor checks health, the executor, and
77
+ the exact seven-tool model-facing surface, then executes a harmless sandbox
78
+ program. The bearer stays in the environment rather than command history.
79
+
80
+ The template refuses to merge into an existing directory, so initialization
81
+ cannot overwrite another project. Its generated programs have no filesystem,
82
+ environment, arbitrary network, imports, or timers; only explicitly read-only
83
+ connector tools are reachable. Unannotated or write-capable calls stay
84
+ individual and cross `call_destructive_tool`, where the MCP host can ask the
85
+ operator for approval.
86
+
87
+ Other supported deployment shapes:
88
+
89
+ - [Prescribed Node template](./templates/node/)
90
+ - [Node repository example](./examples/node/)
91
+ - [Code-first Docker deployment (repository-only)](https://github.com/zackbart/connecta/tree/main/examples/docker)
92
+ - [Cloudflare Worker deployment](./examples/worker/)
93
+ - [Subsystem documentation](./documentation/)
94
+
95
+ Configuring a sandbox — QuickJS on Node or a Dynamic Worker on Cloudflare — is
96
+ what selects the code-first surface and is the assumed posture. A deployment
97
+ without one keeps the earlier nine-tool compatibility interface.
54
98
 
55
99
  ## Project status
56
100
 
@@ -0,0 +1,272 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ copyFile,
5
+ cp,
6
+ lstat,
7
+ mkdtemp,
8
+ readFile,
9
+ rename,
10
+ rm,
11
+ symlink,
12
+ writeFile,
13
+ } from "node:fs/promises";
14
+ import { basename, dirname, join, resolve } from "node:path";
15
+ import { fileURLToPath } from "node:url";
16
+
17
+ const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
18
+ const [command, ...args] = process.argv.slice(2);
19
+
20
+ function shellCd(path) {
21
+ if (process.platform === "win32") {
22
+ return `cd /d "${path.replaceAll('"', '""')}"`;
23
+ }
24
+ return `cd '${path.replaceAll("'", "'\\''")}'`;
25
+ }
26
+
27
+ function usage() {
28
+ console.log(`Usage:
29
+ connecta init [directory]
30
+ CONNECTA_TOKEN=<bearer> connecta doctor [--url http://localhost:8787]`);
31
+ }
32
+
33
+ async function init() {
34
+ if (args.length > 1) {
35
+ usage();
36
+ process.exitCode = 1;
37
+ return;
38
+ }
39
+ const destination = args[0] ?? "connecta-deployment";
40
+ const target = resolve(process.cwd(), destination);
41
+ const parent = dirname(target);
42
+ try {
43
+ await lstat(target);
44
+ throw new Error(`Refusing to overwrite existing path: ${target}`);
45
+ } catch (error) {
46
+ const code =
47
+ error && typeof error === "object" && "code" in error
48
+ ? String(error.code)
49
+ : "";
50
+ if (code !== "ENOENT") throw error;
51
+ }
52
+
53
+ // Build beside the destination, then rename once complete. A failed copy or
54
+ // rewrite leaves no partial destination that blocks a clean retry.
55
+ let stage = await mkdtemp(
56
+ join(parent, `.${basename(target)}.connecta-init-`),
57
+ );
58
+ try {
59
+ await cp(join(packageRoot, "templates", "node"), stage, {
60
+ recursive: true,
61
+ });
62
+
63
+ // npm excludes .gitignore files and symlinks from packed dependencies.
64
+ // Restore both conventions explicitly in the generated project.
65
+ await writeFile(
66
+ join(stage, ".gitignore"),
67
+ ".connecta-state.json\n.env\nnode_modules/\n",
68
+ );
69
+ await rm(join(stage, "CLAUDE.md"), { force: true });
70
+ try {
71
+ await symlink("AGENTS.md", join(stage, "CLAUDE.md"));
72
+ } catch {
73
+ // Some Windows environments disallow symlink creation. A materialized
74
+ // fallback preserves discovery even though AGENTS.md remains canonical.
75
+ await copyFile(join(stage, "AGENTS.md"), join(stage, "CLAUDE.md"));
76
+ }
77
+
78
+ const rootPackage = JSON.parse(
79
+ await readFile(join(packageRoot, "package.json"), "utf8"),
80
+ );
81
+ const deploymentPath = join(stage, "package.json");
82
+ const deploymentPackage = JSON.parse(
83
+ await readFile(deploymentPath, "utf8"),
84
+ );
85
+ deploymentPackage.dependencies["@zackbart/connecta"] = rootPackage.version;
86
+ await writeFile(
87
+ deploymentPath,
88
+ JSON.stringify(deploymentPackage, null, 2) + "\n",
89
+ );
90
+
91
+ await rename(stage, target);
92
+ stage = "";
93
+ } finally {
94
+ if (stage) await rm(stage, { recursive: true, force: true });
95
+ }
96
+
97
+ console.log(`Created ${target}`);
98
+ console.log("Next:");
99
+ console.log(` ${shellCd(target)}`);
100
+ console.log(" npm install");
101
+ console.log(" CONNECTA_TOKEN=dev-token npm start");
102
+ }
103
+
104
+ function option(name, fallback) {
105
+ const index = args.indexOf(name);
106
+ if (index < 0) return fallback;
107
+ const value = args[index + 1];
108
+ if (!value || value.startsWith("--")) {
109
+ throw new Error(`${name} requires a value`);
110
+ }
111
+ return value;
112
+ }
113
+
114
+ async function jsonResponse(response) {
115
+ const text = await response.text();
116
+ if (!response.ok) {
117
+ throw new Error(`HTTP ${response.status}: ${text.slice(0, 500)}`);
118
+ }
119
+ if ((response.headers.get("content-type") ?? "").includes("text/event-stream")) {
120
+ const line = text
121
+ .split("\n")
122
+ .filter((candidate) => candidate.startsWith("data:"))
123
+ .pop();
124
+ if (!line) throw new Error("MCP response contained no SSE data");
125
+ return JSON.parse(line.slice("data:".length).trim());
126
+ }
127
+ return JSON.parse(text);
128
+ }
129
+
130
+ const DOCTOR_TIMEOUT_MS = 10_000;
131
+
132
+ async function doctorFetch(url, init = {}) {
133
+ try {
134
+ return await fetch(url, {
135
+ ...init,
136
+ signal: AbortSignal.timeout(DOCTOR_TIMEOUT_MS),
137
+ });
138
+ } catch (error) {
139
+ if (
140
+ error instanceof Error &&
141
+ (error.name === "TimeoutError" || error.name === "AbortError")
142
+ ) {
143
+ throw new Error(`Timed out after ${DOCTOR_TIMEOUT_MS}ms contacting ${url}`);
144
+ }
145
+ throw error;
146
+ }
147
+ }
148
+
149
+ async function doctor() {
150
+ const known = new Set(["--url"]);
151
+ for (let index = 0; index < args.length; index += 2) {
152
+ if (!known.has(args[index]) || !args[index + 1]) {
153
+ usage();
154
+ process.exitCode = 1;
155
+ return;
156
+ }
157
+ }
158
+ const requestedUrl = option("--url", "http://localhost:8787");
159
+ const parsedUrl = new URL(requestedUrl);
160
+ if (parsedUrl.username || parsedUrl.password) {
161
+ throw new Error("Doctor URL must not contain credentials.");
162
+ }
163
+ if (!["http:", "https:"].includes(parsedUrl.protocol)) {
164
+ throw new Error("Doctor URL must use http or https.");
165
+ }
166
+ const loopbackHosts = new Set(["localhost", "127.0.0.1", "[::1]"]);
167
+ if (
168
+ parsedUrl.protocol === "http:" &&
169
+ !loopbackHosts.has(parsedUrl.hostname)
170
+ ) {
171
+ throw new Error(
172
+ "Refusing to send a bearer token over remote plaintext HTTP. Use HTTPS.",
173
+ );
174
+ }
175
+ const baseUrl = requestedUrl.replace(/\/+$/, "");
176
+ const token = process.env.CONNECTA_TOKEN;
177
+ if (!token) {
178
+ throw new Error(
179
+ "Set CONNECTA_TOKEN so doctor can inspect the MCP surface.",
180
+ );
181
+ }
182
+
183
+ const health = await jsonResponse(
184
+ await doctorFetch(`${baseUrl}/health`),
185
+ );
186
+ if (health.status !== "ok") {
187
+ throw new Error(`Unexpected health status: ${String(health.status)}`);
188
+ }
189
+ if (health.admission?.code === null) {
190
+ throw new Error(
191
+ "The server has no executor and is serving classic compatibility. " +
192
+ "Keep executor: quickJsExecutor() for the prescribed surface.",
193
+ );
194
+ }
195
+
196
+ let requestId = 0;
197
+ const mcp = async (method, params) =>
198
+ jsonResponse(
199
+ await doctorFetch(`${baseUrl}/mcp`, {
200
+ method: "POST",
201
+ headers: {
202
+ Authorization: `Bearer ${token}`,
203
+ "Content-Type": "application/json",
204
+ Accept: "application/json, text/event-stream",
205
+ },
206
+ body: JSON.stringify({
207
+ jsonrpc: "2.0",
208
+ id: ++requestId,
209
+ method,
210
+ params,
211
+ }),
212
+ }),
213
+ );
214
+
215
+ const listed = await mcp("tools/list", {});
216
+ if (listed.error) {
217
+ throw new Error(`tools/list failed: ${JSON.stringify(listed.error)}`);
218
+ }
219
+ const actual = listed.result?.tools
220
+ ?.map((tool) => tool.name)
221
+ .sort();
222
+ const expected = [
223
+ "authorize_connector",
224
+ "call_destructive_tool",
225
+ "call_tool",
226
+ "execute_code",
227
+ "get_result",
228
+ "search_tools",
229
+ "skills",
230
+ ];
231
+ if (JSON.stringify(actual) !== JSON.stringify(expected)) {
232
+ throw new Error(
233
+ `Unexpected MCP surface. Expected ${expected.join(", ")}; received ` +
234
+ `${Array.isArray(actual) ? actual.join(", ") : "no tool list"}.`,
235
+ );
236
+ }
237
+
238
+ const executed = await mcp("tools/call", {
239
+ name: "execute_code",
240
+ arguments: { code: "async () => 42" },
241
+ });
242
+ if (executed.error) {
243
+ throw new Error(`execute_code failed: ${JSON.stringify(executed.error)}`);
244
+ }
245
+ const executionResult =
246
+ executed.result?.structuredContent ??
247
+ JSON.parse(executed.result?.content?.[0]?.text ?? "null");
248
+ if (executed.result?.isError || executionResult?.result !== 42) {
249
+ throw new Error(
250
+ `QuickJS execution check failed: ${JSON.stringify(executed.result)}`,
251
+ );
252
+ }
253
+
254
+ console.log(
255
+ `Connecta doctor passed: ${health.connectors} connector(s), ` +
256
+ "QuickJS executed, prescribed seven-tool surface.",
257
+ );
258
+ }
259
+
260
+ try {
261
+ if (command === "init") await init();
262
+ else if (command === "doctor") await doctor();
263
+ else {
264
+ usage();
265
+ process.exitCode = command === "--help" || command === "-h" ? 0 : 1;
266
+ }
267
+ } catch (error) {
268
+ console.error(
269
+ `[connecta] ${error instanceof Error ? error.message : String(error)}`,
270
+ );
271
+ process.exitCode = 1;
272
+ }
@@ -14,6 +14,11 @@ export declare function boundedDiscoveryText(value: unknown, hint: string): stri
14
14
  export interface CatalogSearchArgs {
15
15
  query?: string;
16
16
  connector?: string;
17
+ /**
18
+ * Result classification only; never changes which tools exist or what may
19
+ * execute. Omitted and "all" preserve the complete configured catalog.
20
+ */
21
+ safety?: "readOnly" | "approvalRequired" | "all";
17
22
  limit?: number;
18
23
  offset?: number;
19
24
  fullDescriptions?: boolean;
@@ -35,6 +40,8 @@ interface CatalogSearchEntry {
35
40
  description?: string;
36
41
  inputSchema?: unknown;
37
42
  outputSchema?: unknown;
43
+ inputSchemaTruncated?: true;
44
+ outputSchemaTruncated?: true;
38
45
  inputKeys?: string[];
39
46
  requiredInputKeys?: string[];
40
47
  outputKeys?: string[];
@@ -49,6 +56,16 @@ export interface CatalogSearchPage {
49
56
  hasMore: boolean;
50
57
  nextOffset?: number;
51
58
  matchMode?: "partial";
59
+ queryAnalysis?: {
60
+ representedTerms: string[];
61
+ otherResultTerms: string[];
62
+ unmatchedTerms: string[];
63
+ truncated?: true;
64
+ connectorScope?: string;
65
+ unknownConnector?: true;
66
+ unavailableConnectorCount?: number;
67
+ guidance?: string;
68
+ };
52
69
  }
53
70
  export interface CatalogDescription {
54
71
  address: string;
@@ -108,12 +125,21 @@ export declare class CatalogService {
108
125
  describe(args: CatalogDescribeArgs): Promise<CatalogDescription[]>;
109
126
  }
110
127
  export declare function groupedSearchResult(page: CatalogSearchPage): {
128
+ queryAnalysis?: {
129
+ representedTerms: string[];
130
+ otherResultTerms: string[];
131
+ unmatchedTerms: string[];
132
+ truncated?: true;
133
+ connectorScope?: string;
134
+ unknownConnector?: true;
135
+ unavailableConnectorCount?: number;
136
+ guidance?: string;
137
+ };
111
138
  matchMode?: "partial";
112
139
  nextOffset?: number;
113
140
  connectors: {
114
141
  id: string;
115
142
  title?: string;
116
- description?: string;
117
143
  guide?: string;
118
144
  tools: CatalogSearchEntry["tool"][];
119
145
  }[];
@@ -123,6 +149,16 @@ export declare function groupedSearchResult(page: CatalogSearchPage): {
123
149
  hasMore: boolean;
124
150
  };
125
151
  export declare function flatSearchResult(page: CatalogSearchPage): {
152
+ queryAnalysis?: {
153
+ representedTerms: string[];
154
+ otherResultTerms: string[];
155
+ unmatchedTerms: string[];
156
+ truncated?: true;
157
+ connectorScope?: string;
158
+ unknownConnector?: true;
159
+ unavailableConnectorCount?: number;
160
+ guidance?: string;
161
+ };
126
162
  matchMode?: "partial";
127
163
  nextOffset?: number;
128
164
  tools: {
@@ -131,6 +167,8 @@ export declare function flatSearchResult(page: CatalogSearchPage): {
131
167
  description?: string;
132
168
  inputSchema?: unknown;
133
169
  outputSchema?: unknown;
170
+ inputSchemaTruncated?: true;
171
+ outputSchemaTruncated?: true;
134
172
  inputKeys?: string[];
135
173
  requiredInputKeys?: string[];
136
174
  outputKeys?: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-service.d.ts","sourceRoot":"","sources":["../src/catalog-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"catalog-service.d.ts","sourceRoot":"","sources":["../src/catalog-service.ts"],"names":[],"mappings":"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"}