argsbarg 6.1.2 → 6.1.3
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/CHANGELOG.md +65 -1
- package/README.md +17 -19
- package/bin/argsbarg +10 -0
- package/docs/README.md +4 -3
- package/docs/ai-skills.md +4 -2
- package/docs/bundled-docs.md +50 -25
- package/docs/cli-program.md +52 -10
- package/docs/config-schema.md +10 -11
- package/docs/configure.md +2 -0
- package/docs/decisions.md +40 -0
- package/docs/developing.md +43 -5
- package/docs/http-server.md +171 -0
- package/docs/json-schema-subset.md +51 -0
- package/docs/mcp.md +4 -2
- package/docs/output-schema.md +55 -62
- package/examples/formats.ts +6 -6
- package/examples/full-example/Formula/full-example.rb +35 -0
- package/examples/full-example/README.md +20 -21
- package/examples/full-example/docs/README.md +1 -1
- package/examples/full-example/docs/cli-schema.json +1790 -98
- package/examples/full-example/docs/cli.md +1990 -0
- package/examples/full-example/docs/http.md +28 -29
- package/examples/full-example/docs/mcp.md +8 -22
- package/examples/full-example/docs/openapi.json +783 -50
- package/examples/full-example/docs/skill.md +10 -10
- package/examples/full-example/justfile +11 -1
- package/examples/full-example/src/commands/render-json/__generated__/RenderJsonInputSchema.json +15 -0
- package/examples/full-example/src/commands/render-json/__generated__/index.ts +5 -0
- package/examples/full-example/src/commands/render-json/command.test.ts +46 -0
- package/examples/full-example/src/commands/render-json/command.ts +30 -0
- package/examples/full-example/src/commands/render-json/types.ts +9 -0
- package/examples/full-example/src/commands/status/__generated__/StatusJsonOutputSchema.json +15 -0
- package/examples/full-example/src/commands/status/__generated__/index.ts +2 -2
- package/examples/full-example/src/commands/status/command.ts +5 -13
- package/examples/full-example/src/commands/status/types.ts +1 -14
- package/examples/full-example/src/commands/workspaces/__generated__/WorkspaceNameInputSchema.json +15 -0
- package/examples/full-example/src/commands/workspaces/__generated__/index.ts +5 -0
- package/examples/full-example/src/commands/workspaces/command.test.ts +58 -0
- package/examples/full-example/src/commands/workspaces/command.ts +94 -0
- package/examples/full-example/src/commands/workspaces/types.ts +6 -0
- package/examples/full-example/src/db/index.test.ts +86 -0
- package/examples/full-example/src/db/index.ts +101 -0
- package/examples/full-example/src/db/migrate.test.ts +35 -0
- package/examples/full-example/src/db/migrate.ts +69 -0
- package/examples/full-example/src/db/migrations/001_workspaces.sql +6 -0
- package/examples/full-example/src/db/tables/workspaces.ts +66 -0
- package/examples/full-example/src/program.ts +11 -36
- package/examples/full-example/src/types/argsbarg.d.ts +11 -0
- package/examples/full-example/src/types/md.d.ts +4 -0
- package/examples/full-example/tsconfig.json +5 -2
- package/examples/mcp-test.ts +1 -2
- package/examples/minimal.ts +1 -7
- package/examples/nested.ts +1 -2
- package/examples/option-required.ts +1 -1
- package/examples/servers.ts +4 -5
- package/index.d.ts +431 -136
- package/package.json +19 -2
- package/src/builtins/builtins.test.ts +7 -7
- package/src/builtins/completion-bash.ts +1 -1
- package/src/builtins/completion-fish.ts +1 -1
- package/src/builtins/completion-group.ts +4 -4
- package/src/builtins/completion-simulate-shared.ts +9 -0
- package/src/builtins/completion-zsh.ts +1 -1
- package/src/builtins/config.test.ts +3 -3
- package/src/builtins/config.ts +9 -9
- package/src/builtins/configure-copy.ts +2 -2
- package/src/builtins/configure.ts +4 -4
- package/src/builtins/dispatch.ts +19 -18
- package/src/builtins/export.ts +7 -5
- package/src/builtins/http.ts +68 -0
- package/src/builtins/mcp.ts +28 -4
- package/src/builtins/presentation.ts +6 -6
- package/src/builtins/registry.ts +6 -6
- package/src/builtins/scopes.ts +2 -2
- package/src/builtins/version.ts +1 -1
- package/src/cli-tool/full-example-capabilities.test.ts +10 -15
- package/src/cli-tool/main.ts +1 -1
- package/src/cli-tool/program.ts +3 -2
- package/src/cli-tool/prompt.ts +1 -1
- package/src/cli-tool/run-schemagen.ts +1 -3
- package/src/cli-tool/schemagen/cleanup.ts +6 -7
- package/src/cli-tool/schemagen/discover-schema-roots.ts +66 -120
- package/src/cli-tool/schemagen/index.ts +2 -2
- package/src/cli-tool/schemagen/names.ts +8 -13
- package/src/cli-tool/schemagen/run.ts +21 -28
- package/src/cli-tool/schemagen/schemagen.test.ts +136 -46
- package/src/config/bindings.test.ts +1 -1
- package/src/config/bindings.ts +1 -1
- package/src/config/bootstrap.test.ts +1 -1
- package/src/config/bootstrap.ts +36 -4
- package/src/config/context.test.ts +1 -1
- package/src/config/context.ts +1 -1
- package/src/config/entry.ts +1 -1
- package/src/config/file.test.ts +1 -1
- package/src/config/file.ts +3 -3
- package/src/config/manifest.ts +1 -1
- package/src/config/resolve.test.ts +1 -1
- package/src/config/resolve.ts +1 -1
- package/src/config/schema.ts +1 -1
- package/src/config/validate.ts +1 -1
- package/src/{install → configure/artifacts}/binary-placement.test.ts +1 -1
- package/src/{install → configure/artifacts}/binary-placement.ts +1 -1
- package/src/{install → configure/artifacts}/gh-release-update.ts +1 -1
- package/src/{install → configure/artifacts}/install-validate.test.ts +3 -3
- package/src/{install → configure/artifacts}/mcp-config.ts +1 -1
- package/src/{install → configure/artifacts}/mcp-opencode.test.ts +1 -1
- package/src/{install → configure/artifacts}/mcp-opencode.ts +1 -1
- package/src/{install → configure/artifacts}/paths.ts +5 -5
- package/src/configure/artifacts/plan.ts +24 -0
- package/src/{install → configure/artifacts}/status.test.ts +1 -1
- package/src/{install → configure/artifacts}/status.ts +2 -2
- package/src/{install → configure/artifacts}/target-base.ts +1 -1
- package/src/{install → configure/artifacts}/target-detect.ts +1 -1
- package/src/{install → configure/artifacts}/target-effective.ts +3 -9
- package/src/{install → configure/artifacts}/target-mcp-cli.ts +1 -1
- package/src/{install → configure/artifacts}/target-mcp-json.ts +1 -1
- package/src/{install → configure/artifacts}/target-plan-build.ts +2 -2
- package/src/{install → configure/artifacts}/target-registry.ts +2 -2
- package/src/{install → configure/artifacts}/target-scope.ts +3 -3
- package/src/{install → configure/artifacts}/target-skill.ts +1 -1
- package/src/{install → configure/artifacts}/target-types.ts +2 -2
- package/src/{install → configure/artifacts}/targets/app.ts +5 -5
- package/src/{install → configure/artifacts}/targets/chatgpt-mcp.ts +2 -2
- package/src/{install → configure/artifacts}/targets/claude-code-mcp.ts +2 -2
- package/src/{install → configure/artifacts}/targets/claude-desktop-mcp.ts +2 -2
- package/src/{install → configure/artifacts}/targets/claude-skill.ts +2 -2
- package/src/{install → configure/artifacts}/targets/codex-mcp.ts +2 -2
- package/src/{install → configure/artifacts}/targets/codex-skill.ts +2 -2
- package/src/{install → configure/artifacts}/targets/configure.ts +5 -5
- package/src/{install → configure/artifacts}/targets/cursor-mcp.ts +2 -2
- package/src/{install → configure/artifacts}/targets/cursor-skill.ts +2 -2
- package/src/{install → configure/artifacts}/targets/index.ts +1 -1
- package/src/{install → configure/artifacts}/targets/openclaw-mcp.ts +2 -2
- package/src/{install → configure/artifacts}/targets/openclaw-skill.ts +3 -3
- package/src/{install → configure/artifacts}/targets/opencode-mcp.ts +5 -5
- package/src/{install → configure/artifacts}/targets/opencode-skill.ts +3 -3
- package/src/{install → configure/artifacts}/targets.test.ts +1 -1
- package/src/{install → configure/artifacts}/uninstall.ts +1 -1
- package/src/configure/configure.test.ts +11 -11
- package/src/configure/index.ts +14 -14
- package/src/configure/prompt.ts +2 -2
- package/src/{context.ts → core/context.ts} +26 -20
- package/src/{json-leaf.test.ts → core/json-leaf.test.ts} +4 -4
- package/src/{leaf-inputs.test.ts → core/leaf-inputs.test.ts} +7 -7
- package/src/{leaf-inputs.ts → core/leaf-inputs.ts} +16 -12
- package/src/{parse.test.ts → core/parse.test.ts} +97 -109
- package/src/{parse.ts → core/parse.ts} +129 -31
- package/src/{schema.ts → core/schema.ts} +25 -13
- package/src/{types.ts → core/types.ts} +225 -35
- package/src/{validate.ts → core/validate.ts} +39 -29
- package/src/docs/builtin.ts +8 -19
- package/src/docs/{api-guide.test.ts → cli-guide.test.ts} +21 -21
- package/src/docs/{api-guide.ts → cli-guide.ts} +45 -16
- package/src/docs/docs.test.ts +76 -41
- package/src/docs/http-guide.ts +37 -34
- package/src/docs/mcp-guide.ts +12 -14
- package/src/docs/mcp-resources.test.ts +2 -3
- package/src/docs/mcp-resources.ts +6 -11
- package/src/docs/resolve.ts +22 -30
- package/src/docs/save.ts +3 -3
- package/src/exports/cli.ts +47 -0
- package/src/exports/headless.ts +13 -0
- package/src/exports/http.ts +6 -0
- package/src/exports/mcp.ts +6 -0
- package/src/{headless.test.ts → headless/routing.test.ts} +3 -3
- package/src/{headless.ts → headless/routing.ts} +3 -3
- package/src/headless/tool-call.ts +114 -46
- package/src/help.test.ts +152 -0
- package/src/help.ts +3 -3
- package/src/hooks/builtin.ts +20 -0
- package/src/hooks/run.ts +142 -0
- package/src/http/openapi.ts +182 -0
- package/src/http/readiness.ts +78 -0
- package/src/{api → http}/result.ts +16 -5
- package/src/http/routes.ts +329 -0
- package/src/http/server.ts +225 -0
- package/src/index.ts +36 -25
- package/src/log/ecs.test.ts +43 -0
- package/src/log/ecs.ts +59 -0
- package/src/log/emitter.ts +166 -0
- package/src/mcp/bundle.ts +2 -2
- package/src/mcp/claude.test.ts +1 -1
- package/src/mcp/claude.ts +4 -4
- package/src/{hidden-mcpb.test.ts → mcp/hidden-mcpb.test.ts} +10 -9
- package/src/mcp/result.ts +2 -2
- package/src/mcp/server.ts +54 -6
- package/src/mcp/tools.ts +9 -20
- package/src/{capabilities.ts → runtime/capabilities.ts} +11 -11
- package/src/{cli-errors.ts → runtime/cli-errors.ts} +4 -4
- package/src/{cli.ts → runtime/cli.ts} +159 -49
- package/src/runtime/exposure.ts +102 -0
- package/src/{invoke.test.ts → runtime/invoke.test.ts} +31 -7
- package/src/server/context.ts +25 -0
- package/src/server/overrides.ts +112 -0
- package/src/skill/generate.ts +8 -8
- package/src/skill/hint.ts +1 -1
- package/src/skill/install.ts +2 -2
- package/src/skill/naming.ts +1 -1
- package/src/{test-fixtures.ts → test/fixtures.ts} +3 -2
- package/src/{config.integration.test.ts → test/integration/config.test.ts} +8 -8
- package/src/{api.integration.test.ts → test/integration/http.test.ts} +170 -67
- package/src/{mcp.integration.test.ts → test/integration/mcp.test.ts} +11 -57
- package/docs/api-server.md +0 -141
- package/examples/full-example/docs/api.md +0 -511
- package/examples/full-example/src/commands/status/__generated__/outputSchema.json +0 -28
- package/examples/full-example/src/config/__generated__/configSchema.json +0 -40
- package/examples/full-example/src/config/__generated__/index.ts +0 -5
- package/examples/full-example/src/config/types.ts +0 -24
- package/src/api/openapi.ts +0 -117
- package/src/api/server.ts +0 -120
- package/src/builtins/api.ts +0 -38
- package/src/hidden.ts +0 -30
- package/src/install/plan.ts +0 -53
- /package/src/{install → configure/artifacts}/detect-installed.ts +0 -0
- /package/src/{install → configure/artifacts}/gh-release-update.test.ts +0 -0
- /package/src/{install → configure/artifacts}/mcp-codex.test.ts +0 -0
- /package/src/{install → configure/artifacts}/mcp-codex.ts +0 -0
- /package/src/{install → configure/artifacts}/mcp-openclaw.test.ts +0 -0
- /package/src/{install → configure/artifacts}/mcp-openclaw.ts +0 -0
- /package/src/{install → configure/artifacts}/normalize-uninstall.ts +0 -0
- /package/src/{install → configure/artifacts}/normalize.ts +0 -0
- /package/src/{install → configure/artifacts}/opts.ts +0 -0
- /package/src/{install → configure/artifacts}/shell.ts +0 -0
- /package/src/{formats.test.ts → core/formats.test.ts} +0 -0
- /package/src/{formats.ts → core/formats.ts} +0 -0
- /package/src/{respond.ts → core/respond.ts} +0 -0
- /package/src/{types.test.ts → core/types.test.ts} +0 -0
- /package/src/{api → http}/schema-deref.test.ts +0 -0
- /package/src/{api → http}/schema-deref.ts +0 -0
|
@@ -5,19 +5,18 @@ Domain-specific regression tests (split from index.test.ts).
|
|
|
5
5
|
import { expect, test } from "bun:test";
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import { $ } from "bun";
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
8
|
+
import { cliSchemaExport } from "~/core/schema.ts";
|
|
9
|
+
import { cliValidateProgram } from "~/core/validate.ts";
|
|
10
|
+
import type { CliProgram } from "~/index";
|
|
11
|
+
import { buildToolCallSuccessFromResponse } from "~/mcp/result.ts";
|
|
10
12
|
import {
|
|
11
|
-
apiToolName,
|
|
12
13
|
collectMcpTools,
|
|
13
14
|
mcpToolCallToArgv,
|
|
14
15
|
mcpToolDescription,
|
|
15
16
|
mcpToolName,
|
|
16
17
|
sanitizeToolSegment,
|
|
17
|
-
} from "
|
|
18
|
-
import {
|
|
19
|
-
import { mcpRequest, nestedMcpFixture, testProgram } from "./test-fixtures.ts";
|
|
20
|
-
import { cliValidateProgram } from "./validate.ts";
|
|
18
|
+
} from "~/mcp/tools.ts";
|
|
19
|
+
import { mcpRequest, nestedMcpFixture, testProgram } from "~/test/fixtures.ts";
|
|
21
20
|
|
|
22
21
|
test("sanitizeToolSegment normalizes dotted app keys", () => {
|
|
23
22
|
expect(sanitizeToolSegment("minimal.ts")).toBe("minimal_ts");
|
|
@@ -31,10 +30,8 @@ test("mcpToolDescription formats CLI path and root-leaf prefix", () => {
|
|
|
31
30
|
expect(mcpToolDescription([], "helloapp", "Tiny demo.")).toBe("helloapp — Tiny demo.");
|
|
32
31
|
});
|
|
33
32
|
|
|
34
|
-
test("
|
|
35
|
-
expect(apiToolName(nestedMcpFixture, ["stat", "owner", "lookup"])).toBe("stat-owner-lookup");
|
|
33
|
+
test("mcpToolName sanitizes path segments to underscores", () => {
|
|
36
34
|
expect(mcpToolName(nestedMcpFixture, ["stat", "owner", "lookup"])).toBe("stat_owner_lookup");
|
|
37
|
-
expect(apiToolName(nestedMcpFixture, ["render-invoice"])).toBe("render-invoice");
|
|
38
35
|
expect(mcpToolName(nestedMcpFixture, ["render-invoice"])).toBe("render_invoice");
|
|
39
36
|
});
|
|
40
37
|
|
|
@@ -43,7 +40,6 @@ test("collectMcpTools lists user leaf commands only", () => {
|
|
|
43
40
|
const names = tools.map((t) => t.name);
|
|
44
41
|
expect(names).toContain("stat_owner_lookup");
|
|
45
42
|
const lookup = tools.find((t) => t.name === "stat_owner_lookup")!;
|
|
46
|
-
expect(lookup.apiName).toBe("stat-owner-lookup");
|
|
47
43
|
expect(lookup.description).toBe("stat owner lookup — Resolve owner info.");
|
|
48
44
|
expect(names).toContain("read");
|
|
49
45
|
expect(names).not.toContain("hidden");
|
|
@@ -104,13 +100,13 @@ test("collectMcpTools resolves {argsbarg:program} in appended notes", () => {
|
|
|
104
100
|
{
|
|
105
101
|
key: "run",
|
|
106
102
|
description: "Run.",
|
|
107
|
-
notes: "See `{argsbarg:program} docs
|
|
103
|
+
notes: "See `{argsbarg:program} docs cli`.",
|
|
108
104
|
handler: () => {},
|
|
109
105
|
},
|
|
110
106
|
],
|
|
111
107
|
});
|
|
112
108
|
const tools = collectMcpTools(root);
|
|
113
|
-
expect(tools[0]?.description).toContain("See `myapp docs
|
|
109
|
+
expect(tools[0]?.description).toContain("See `myapp docs cli`.");
|
|
114
110
|
});
|
|
115
111
|
|
|
116
112
|
/** CliSchemaExport includes leaf outputSchema. */
|
|
@@ -139,29 +135,6 @@ test("cliSchemaExport includes leaf outputSchema", () => {
|
|
|
139
135
|
});
|
|
140
136
|
});
|
|
141
137
|
|
|
142
|
-
/** CliSchemaExport accepts legacy mcpTool.outputSchema. */
|
|
143
|
-
test("cliSchemaExport accepts legacy mcpTool.outputSchema", () => {
|
|
144
|
-
const root = testProgram({
|
|
145
|
-
key: "app",
|
|
146
|
-
version: "1.0.0",
|
|
147
|
-
description: "Schema export demo.",
|
|
148
|
-
commands: [
|
|
149
|
-
{
|
|
150
|
-
key: "run",
|
|
151
|
-
description: "Run.",
|
|
152
|
-
mcpTool: {
|
|
153
|
-
outputSchema: { type: "object", properties: { id: { type: "string" } } },
|
|
154
|
-
},
|
|
155
|
-
handler: () => {},
|
|
156
|
-
},
|
|
157
|
-
],
|
|
158
|
-
});
|
|
159
|
-
expect(cliSchemaExport(root).commands?.[0]?.outputSchema).toEqual({
|
|
160
|
-
type: "object",
|
|
161
|
-
properties: { id: { type: "string" } },
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
|
|
165
138
|
/** Tests that outputSchema must be a JSON Schema object. */
|
|
166
139
|
test("outputSchema must be a JSON Schema object", () => {
|
|
167
140
|
const root = testProgram({
|
|
@@ -180,25 +153,6 @@ test("outputSchema must be a JSON Schema object", () => {
|
|
|
180
153
|
expect(() => cliValidateProgram(root)).toThrow(/outputSchema must be a JSON Schema object/);
|
|
181
154
|
});
|
|
182
155
|
|
|
183
|
-
/** Tests that outputSchema cannot be set on both leaf and mcpTool. */
|
|
184
|
-
test("outputSchema cannot be set on both leaf and mcpTool", () => {
|
|
185
|
-
const root = testProgram({
|
|
186
|
-
key: "app",
|
|
187
|
-
version: "1.0.0",
|
|
188
|
-
description: "Duplicate output schema.",
|
|
189
|
-
commands: [
|
|
190
|
-
{
|
|
191
|
-
key: "run",
|
|
192
|
-
description: "Run.",
|
|
193
|
-
outputSchema: { type: "object" },
|
|
194
|
-
mcpTool: { outputSchema: { type: "object" } },
|
|
195
|
-
handler: () => {},
|
|
196
|
-
},
|
|
197
|
-
],
|
|
198
|
-
});
|
|
199
|
-
expect(() => cliValidateProgram(root)).toThrow(/Set outputSchema on the leaf only/);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
156
|
test("collectMcpTools merges parent options into inputSchema", () => {
|
|
203
157
|
const tools = collectMcpTools(nestedMcpFixture);
|
|
204
158
|
const lookup = tools.find((t) => t.name === "stat_owner_lookup")!;
|
|
@@ -419,7 +373,7 @@ test("MCP resources/read returns schema JSON", async () => {
|
|
|
419
373
|
|
|
420
374
|
/** MCP tools/call runs stat_owner_lookup. */
|
|
421
375
|
test("MCP tools/call runs stat_owner_lookup", async () => {
|
|
422
|
-
const readme = join(import.meta.dir, "..", "README.md");
|
|
376
|
+
const readme = join(import.meta.dir, "..", "..", "..", "README.md");
|
|
423
377
|
const responses = await mcpRequest([
|
|
424
378
|
{
|
|
425
379
|
jsonrpc: "2.0",
|
|
@@ -440,7 +394,7 @@ test("MCP tools/call runs stat_owner_lookup", async () => {
|
|
|
440
394
|
|
|
441
395
|
/** MCP tools/call returns structuredContent for JSON stdout. */
|
|
442
396
|
test("MCP tools/call returns structuredContent for JSON stdout", async () => {
|
|
443
|
-
const readme = join(import.meta.dir, "..", "README.md");
|
|
397
|
+
const readme = join(import.meta.dir, "..", "..", "..", "README.md");
|
|
444
398
|
const responses = await mcpRequest([
|
|
445
399
|
{
|
|
446
400
|
jsonrpc: "2.0",
|
package/docs/api-server.md
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
# HTTP API server
|
|
2
|
-
|
|
3
|
-
ArgsBarg can expose your CLI as an HTTP tool server. Each **leaf command** becomes a callable tool — the same exposure model as MCP. The server uses Bun's built-in HTTP stack and binds to **localhost by default**.
|
|
4
|
-
|
|
5
|
-
The HTTP API is **opt-in**. Apps that do not set `apiServer` on the program root behave exactly as before.
|
|
6
|
-
|
|
7
|
-
## Quick start
|
|
8
|
-
|
|
9
|
-
1. Add `apiServer` to your program root:
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
import pkg from "../package.json" with { type: "json" };
|
|
13
|
-
|
|
14
|
-
const cli = {
|
|
15
|
-
key: "myapp",
|
|
16
|
-
version: pkg.version,
|
|
17
|
-
description: "My app.",
|
|
18
|
-
apiServer: { enabled: true },
|
|
19
|
-
commands: [/* ... */],
|
|
20
|
-
} satisfies CliProgram;
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
`apiServer: { enabled: true }` opts in. Omit `apiServer` entirely to disable HTTP. Empty `apiServer: {}` is rejected at validation.
|
|
24
|
-
|
|
25
|
-
2. Run the HTTP server:
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
myapp api
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
The process listens until interrupted. Startup prints the listen URL to stderr.
|
|
32
|
-
|
|
33
|
-
## Configuration
|
|
34
|
-
|
|
35
|
-
Set `apiServer` on the **program root only**. Validation rejects `apiServer` on nested nodes.
|
|
36
|
-
|
|
37
|
-
| Field | Default | Purpose |
|
|
38
|
-
| --- | --- | --- |
|
|
39
|
-
| `enabled` | *(required)* | Must be `true` when `apiServer` is set |
|
|
40
|
-
| `host` | `127.0.0.1` | Listen address |
|
|
41
|
-
| `port` | `3000` | Listen port |
|
|
42
|
-
|
|
43
|
-
`apiServer` and `mcpServer` are independent — enable either or both.
|
|
44
|
-
|
|
45
|
-
## Tool names
|
|
46
|
-
|
|
47
|
-
HTTP and MCP use different tool identifiers for the same leaf command:
|
|
48
|
-
|
|
49
|
-
| CLI path | HTTP API (`POST /tools/:name`) | MCP (`tools/call`) |
|
|
50
|
-
| --- | --- | --- |
|
|
51
|
-
| `stat owner lookup` | `stat-owner-lookup` | `stat_owner_lookup` |
|
|
52
|
-
| `render-invoice` | `render-invoice` | `render_invoice` |
|
|
53
|
-
|
|
54
|
-
OpenAPI `paths` use the API id (`/tools/render-invoice`, etc.).
|
|
55
|
-
|
|
56
|
-
## Endpoints
|
|
57
|
-
|
|
58
|
-
| Method | Path | Purpose |
|
|
59
|
-
| --- | --- | --- |
|
|
60
|
-
| `GET` | `/health` | Liveness check |
|
|
61
|
-
| `GET` | `/openapi.json` | OpenAPI 3.1 document (per-tool `POST /tools/{name}` paths) |
|
|
62
|
-
| `GET` | `/openapi-browser` | Interactive Scalar API reference (CDN) |
|
|
63
|
-
| `POST` | `/tools/:name` | Invoke tool; body is a flat JSON args object |
|
|
64
|
-
| `OPTIONS` | `*` | CORS preflight (wide-open `Access-Control-Allow-Origin: *`) |
|
|
65
|
-
|
|
66
|
-
## Examples
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
curl -s http://127.0.0.1:3000/health
|
|
70
|
-
curl -s http://127.0.0.1:3000/openapi.json
|
|
71
|
-
open http://127.0.0.1:3000/openapi-browser
|
|
72
|
-
curl -s -X POST http://127.0.0.1:3000/tools/{tool-key} \
|
|
73
|
-
-H 'content-type: application/json' \
|
|
74
|
-
-d '{...}'
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
Replace `{tool-key}` with a path segment from `openapi.json` (`paths` keys are `/tools/{tool-key}`); body keys match that tool's flat JSON args (see `docs cli-schema` or `openapi.json`).
|
|
78
|
-
|
|
79
|
-
## Handler responses (`ctx.respond()`)
|
|
80
|
-
|
|
81
|
-
API and MCP tool handlers must return machine-readable output via **`ctx.respond()`** or by **returning a value** (implicit JSON). `console.log` is not included in HTTP/MCP success payloads.
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
handler: (ctx) => {
|
|
85
|
-
if (ctx.hasFlag("json")) {
|
|
86
|
-
return { user: "alice", path: "/tmp" };
|
|
87
|
-
}
|
|
88
|
-
ctx.respond({
|
|
89
|
-
body: pdfBytes,
|
|
90
|
-
contentType: "application/pdf",
|
|
91
|
-
headers: { "Content-Disposition": 'inline; filename="invoice.pdf"' },
|
|
92
|
-
});
|
|
93
|
-
},
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
**CLI mode:** `ctx.respond()` prints to stdout (JSON pretty-printed, strings as-is, `Uint8Array` as raw bytes). Handlers may still use `console.log` for human-only CLI output.
|
|
97
|
-
|
|
98
|
-
### Leaf metadata
|
|
99
|
-
|
|
100
|
-
```typescript
|
|
101
|
-
apiResponse?: {
|
|
102
|
-
contentType?: string; // default application/json
|
|
103
|
-
contentDisposition?: string; // e.g. attachment; filename="invoice.pdf"
|
|
104
|
-
};
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
Used by OpenAPI and as a default `Content-Type` when the handler does not set one.
|
|
108
|
-
|
|
109
|
-
## Responses
|
|
110
|
-
|
|
111
|
-
**Success (`200`):** raw body — no `{ ok, stdout }` envelope.
|
|
112
|
-
|
|
113
|
-
| Body type | HTTP `Content-Type` |
|
|
114
|
-
| --- | --- |
|
|
115
|
-
| object / array | `application/json` |
|
|
116
|
-
| string | handler `contentType` or `text/plain` |
|
|
117
|
-
| `Uint8Array` | e.g. `application/pdf` (required on `respond()`) |
|
|
118
|
-
|
|
119
|
-
**Errors:** JSON `{ "error": "...", "exitCode?": number }` with `400` (bad args), `404` (unknown tool), `503` (missing config), or `500` (handler failure).
|
|
120
|
-
|
|
121
|
-
## MCP binary payloads
|
|
122
|
-
|
|
123
|
-
Binary `ctx.respond()` bodies are encoded in MCP `structuredContent` as:
|
|
124
|
-
|
|
125
|
-
```json
|
|
126
|
-
{ "data": "<base64>", "contentType": "application/pdf", "encoding": "base64" }
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
String bodies use `{ "content": "...", "contentType": "..." }`. JSON objects are returned as-is in `structuredContent`.
|
|
130
|
-
|
|
131
|
-
## CORS
|
|
132
|
-
|
|
133
|
-
All responses include wide-open CORS headers (`Access-Control-Allow-Origin: *`). Not configurable in v1.
|
|
134
|
-
|
|
135
|
-
## OpenAPI
|
|
136
|
-
|
|
137
|
-
Call `generateOpenApi(program)` or `openApiJson(program)` from the package, fetch `GET /openapi.json` from a running server, or run `myapp docs openapi` / `myapp docs openapi --save` (writes `./docs/openapi.json` when `docs.enabled` and `apiServer.enabled`). Nested `inputSchema` / `outputSchema` `$ref` pointers are dereferenced when the OpenAPI document is built so API reference UIs can show nested request shapes.
|
|
138
|
-
|
|
139
|
-
## Complex tool inputs
|
|
140
|
-
|
|
141
|
-
For nested request bodies (e.g. invoice template data), set `inputSchema` on the leaf, declare a matching `kind: Json` option (optionally `pipable: true` for CLI stdin), and read inputs with `ctx.jsonOpt(...)` or `ctx.readLeafInputs()` — piped stdin is loaded before the handler runs.
|