@ductape/mcp 0.2.30 → 0.2.32
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 +1 -0
- package/dist/index.js +185 -30
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
- Added `cli-authentication` guidance for automatic Google/GitHub browser OAuth, validated loopback callbacks, trusted-terminal handoff, credential non-disclosure, and external session refresh.
|
|
9
10
|
- Added source-verified graph/vector projection guidance to the `features`, `events`, `graphs`, and `vector` docs topics, including exact graph/vector payloads, NestJS consumer routing, replay/idempotency, projection-state ordering, rebuild/drift repair, and an explicit stop condition for the currently missing code-first `ctx.vector` API.
|
|
10
11
|
- Added read-only `ductape_events_topic_setup` and `ductape_events_validate_project` tools and made the canonical one-topic-per-file `ductape/events/<topic-tag>.topic.json` layout explicit and enforceable through the CLI.
|
|
11
12
|
- Mark `ductape_function_setup` as read-only, non-destructive, idempotent, and closed-world in both MCP registration APIs so hosts do not incorrectly require mutation approval for its pure setup-plan generation.
|
package/dist/index.js
CHANGED
|
@@ -909,12 +909,13 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
|
|
|
909
909
|
vector.deleteIndex [{ product, env, vector, name }]
|
|
910
910
|
vector.listIndexes [{ product, env, vector }]
|
|
911
911
|
vector.count [{ product, env, vector, namespace? }]
|
|
912
|
-
vector.
|
|
913
|
-
vector.
|
|
914
|
-
vector.
|
|
915
|
-
vector.
|
|
916
|
-
vector.
|
|
917
|
-
vector.
|
|
912
|
+
vector.action.create [{ product, vector, actionTag, name, operation, template, description?, parameters? }]
|
|
913
|
+
vector.action.update [{ product, vector, actionTag, name?, description?, template?, parameters? }]
|
|
914
|
+
vector.action.fetch [{ product, vector, actionTag }]
|
|
915
|
+
vector.action.fetchAll [{ product, vector }]
|
|
916
|
+
vector.action.delete [{ product, vector, actionTag }]
|
|
917
|
+
vector.action.execute [{ product, env, vector, action, input, session? }]
|
|
918
|
+
← synchronous saved-action execution. Do not use vector.query for a saved action.
|
|
918
919
|
|
|
919
920
|
━━━ MODULE: features ━━━
|
|
920
921
|
Feature definitions are code-first. Use features.define in application source; do not call
|
|
@@ -944,6 +945,9 @@ ALL params are passed as a JSON array in positional order matching the SDK signa
|
|
|
944
945
|
// ctx.input – typed runtime input; always compiles to $Input{} operators
|
|
945
946
|
// ctx.sampleInput – compile-time sample for loop/branch discovery only
|
|
946
947
|
// ctx.step(tag, fn, rollback?, opts?) – define a durable step
|
|
948
|
+
// ctx.when.eq/ne/gt/gte/lt/lte/truthy/falsy(...) – build portable runtime conditions
|
|
949
|
+
// ctx.branch(condition, { then, else? }) – record both paths as conditioned steps
|
|
950
|
+
// ctx.each(ctx.sampleInput.items, async (item, index) => ...) – deterministic compile-time expansion
|
|
947
951
|
// ctx.api.run({ app, action, input }) – call an app action (NOT 'event' -- that field name
|
|
948
952
|
// only applies to ctx.database/ctx.notification/ctx.storage below, never ctx.api/ctx.action)
|
|
949
953
|
// ctx.database.execute({ database, action, input }) for a saved database action
|
|
@@ -1500,6 +1504,7 @@ function runCli(command) {
|
|
|
1500
1504
|
'or use an OAuth flow:',
|
|
1501
1505
|
' ductape login --browser google',
|
|
1502
1506
|
' ductape login --browser github',
|
|
1507
|
+
'Browser OAuth returns to the CLI automatically through a validated 127.0.0.1 callback.',
|
|
1503
1508
|
'',
|
|
1504
1509
|
'Do not paste a password, OAuth callback token, or stored CLI credential into an agent prompt.',
|
|
1505
1510
|
'After login succeeds, retry the same ductape_cli command.',
|
|
@@ -1551,7 +1556,7 @@ const docsInputSchema = z.object({
|
|
|
1551
1556
|
topic: z.string().describe('Feature topic to look up. Supported: ' +
|
|
1552
1557
|
'transactions, presave, triggers, aggregations, migrations, indexes, performance, actions, ' +
|
|
1553
1558
|
'graphs, storage, cloud, vector, warehouse, secrets, apps, products, sessions, caches, ' +
|
|
1554
|
-
'notifications, resilience, features, portable-functions, events, logs, migration, frontend, frontend-analytics, client, react, vue'),
|
|
1559
|
+
'notifications, resilience, features, portable-functions, events, logs, migration, cli-authentication, frontend, frontend-analytics, client, react, vue'),
|
|
1555
1560
|
});
|
|
1556
1561
|
const eventsDiscoveryInputSchema = z.object({
|
|
1557
1562
|
query: z.string().optional().describe('Capability or recovery search, including DLQ, dead letter, failed messages, retry, poison message, replay, or consumer failure.'),
|
|
@@ -1607,6 +1612,34 @@ const migrationInputSchema = z.object({
|
|
|
1607
1612
|
write: z.boolean().optional().default(false).describe('Write redacted advisory artifacts only. This never writes application code or executable Ductape assets.'),
|
|
1608
1613
|
});
|
|
1609
1614
|
const DOCS = {
|
|
1615
|
+
'cli-authentication': `
|
|
1616
|
+
DUCTAPE CLI AUTHENTICATION
|
|
1617
|
+
|
|
1618
|
+
For an interactive local login, prefer browser OAuth:
|
|
1619
|
+
ductape login --browser google
|
|
1620
|
+
ductape login --browser github
|
|
1621
|
+
|
|
1622
|
+
The CLI opens the provider in the user's browser, starts a temporary loopback listener on
|
|
1623
|
+
127.0.0.1, validates the returned OAuth state, exchanges the callback token, stores the resulting
|
|
1624
|
+
session in the local Ductape credential store, and then continues workspace selection. The user
|
|
1625
|
+
does not copy a callback token or share credentials with an agent.
|
|
1626
|
+
|
|
1627
|
+
Run browser login only in the user's trusted local terminal. An MCP tool, agent subprocess, CI
|
|
1628
|
+
runner, container, SSH session, or remote development host may not own the browser's loopback
|
|
1629
|
+
interface. Do not invoke interactive login through ductape_cli and do not ask the user to paste a
|
|
1630
|
+
password, OAuth callback token, auth token, or stored credential into chat.
|
|
1631
|
+
|
|
1632
|
+
Use email/password login only when the user deliberately chooses it in their own terminal:
|
|
1633
|
+
ductape login
|
|
1634
|
+
|
|
1635
|
+
Use --token only as a compatibility or automation fallback when the user already possesses a
|
|
1636
|
+
valid OAuth callback token through a trusted flow. Never solicit that token in an agent prompt.
|
|
1637
|
+
|
|
1638
|
+
After login succeeds, retry the original ductape_cli operation. The MCP re-reads a previously
|
|
1639
|
+
missing or expired external CLI session without requiring an MCP restart. If a command returns
|
|
1640
|
+
HTTP 401 while workspace reads still succeed, treat it as endpoint authorization or command
|
|
1641
|
+
routing failure, not as a reason to re-authenticate.
|
|
1642
|
+
`.trim(),
|
|
1610
1643
|
'portable-functions': `
|
|
1611
1644
|
PORTABLE APPLICATION FUNCTIONS
|
|
1612
1645
|
|
|
@@ -2551,10 +2584,12 @@ Schema management:
|
|
|
2551
2584
|
graph.dropIndex / dropConstraint / listIndexes / listConstraints
|
|
2552
2585
|
|
|
2553
2586
|
Saved actions (parameterized queries stored on the product):
|
|
2554
|
-
graph.
|
|
2555
|
-
graph.
|
|
2556
|
-
graph.
|
|
2557
|
-
graph.
|
|
2587
|
+
graph.action.create [{ product, graph|graphTag, name, description?, operation, query, parameters? }]
|
|
2588
|
+
graph.action.fetchAll [{ product, graph|graphTag }]
|
|
2589
|
+
graph.action.fetch [{ product, graph|graphTag, action|actionTag }]
|
|
2590
|
+
graph.action.execute [{ product, env, graph, action, input, session? }]
|
|
2591
|
+
graph.action.dispatch [{ product, env, graph, event, input, schedule? }] ← call ductape_generate_payload FIRST
|
|
2592
|
+
Use graph.action.execute for a saved action. graph.query is only for a direct provider-native query.
|
|
2558
2593
|
|
|
2559
2594
|
Supported index types: btree | fulltext | vector | range | point | text
|
|
2560
2595
|
Supported constraint types: UNIQUE | EXISTS | NODE_KEY
|
|
@@ -3341,6 +3376,20 @@ CONFIGURATION BOUNDARY
|
|
|
3341
3376
|
Workbench is also supported. Never route their administrative create/update methods through
|
|
3342
3377
|
ductape_execute: its publishable-key runtime proxy will fail.
|
|
3343
3378
|
|
|
3379
|
+
CLI COMMANDS (aliases are normalized; use these exact shapes):
|
|
3380
|
+
ductape resources feature list --product <product> --json
|
|
3381
|
+
ductape resources feature get -t <feature> --product <product> --json
|
|
3382
|
+
ductape resources quota list --product <product> --json
|
|
3383
|
+
ductape resources quota get -t <quota> --product <product> --json
|
|
3384
|
+
ductape resources fallback list --product <product> --json
|
|
3385
|
+
ductape resources fallback get -t <fallback> --product <product> --json
|
|
3386
|
+
ductape resources health list --product <product> --json
|
|
3387
|
+
ductape resources health get -t <healthcheck> --product <product> --json
|
|
3388
|
+
Create/update use the same resource type plus -f <asset.json>. Singular/plural feature(s),
|
|
3389
|
+
fallback(s), and healthcheck(s) aliases are accepted, but canonical generated commands should
|
|
3390
|
+
use feature, quota, fallback, and health. These commands are administrative catalogue CRUD;
|
|
3391
|
+
runtime run/execute operations belong to the SDK or authenticated execution surface.
|
|
3392
|
+
|
|
3344
3393
|
QUOTAS — weighted/provider-capacity routing pools (NOT request rate limiting):
|
|
3345
3394
|
Workbench definition shape:
|
|
3346
3395
|
{
|
|
@@ -3897,15 +3946,83 @@ STEP 6 — WRITE the feature into the project codebase
|
|
|
3897
3946
|
script does, invoked only through the explicit CLI command.
|
|
3898
3947
|
|
|
3899
3948
|
STEP 7 — HANDLE conditionals, loops, and branching (when applicable)
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3949
|
+
MANDATORY CONTROL-FLOW RULES:
|
|
3950
|
+
1. A stored Feature executes its compiled steps. The JavaScript handler is NOT rerun at runtime.
|
|
3951
|
+
2. Never use if/else, switch, ?:, ??, &&, ||, optional chaining, map, filter, find, some,
|
|
3952
|
+
every, reduce, for, for..of, forEach, or while on a ctx.step() result or ctx.input proxy.
|
|
3953
|
+
JavaScript would evaluate the recording proxy, not the future runtime value.
|
|
3954
|
+
3. Use ctx.branch(ctx.when.*, { then, else }) for runtime decisions.
|
|
3955
|
+
4. Use ctx.each only with a concrete ctx.sampleInput array to expand a fixed step graph.
|
|
3956
|
+
5. Put runtime-sized collection algorithms and arbitrary business logic in a registered
|
|
3957
|
+
portable Function, then invoke it through ctx.functions inside a step.
|
|
3958
|
+
6. Direct Date.now() and Math.random() are forbidden in handlers. Use ctx.transform.now(),
|
|
3959
|
+
ctx.transform.uuid(), and ctx.transform.concat/replace/substring/upper/lower/trim so values
|
|
3960
|
+
are generated at execution time. Use a portable Function for domain-specific generators.
|
|
3961
|
+
7. Never use branchOverrides in newly generated code. It exists only to migrate old handlers.
|
|
3962
|
+
|
|
3963
|
+
Prefer explicit portable branching for step results:
|
|
3964
|
+
const result = await ctx.step("find", () => ctx.database.execute(...));
|
|
3965
|
+
await ctx.branch(ctx.when.eq(result.count, 0), {
|
|
3966
|
+
then: () => ctx.step("create", () => ctx.database.execute(...)),
|
|
3967
|
+
else: () => ctx.step("reuse", () => ctx.database.execute(...)),
|
|
3968
|
+
});
|
|
3969
|
+
→ ctx.when also supports ne, gt, gte, lt, lte, truthy, falsy, and/or.
|
|
3970
|
+
→ Do not use ordinary if/else, ternary, or ?? directly on an unresolved step result.
|
|
3971
|
+
→ branchOverrides remains a compatibility escape hatch for older Feature source.
|
|
3972
|
+
→ If both paths must feed a later common step, do not assume ctx.branch returns a selected
|
|
3973
|
+
value. Either record the downstream operation inside each path, persist a shared result that
|
|
3974
|
+
the later step can read, or move the find-or-create algorithm into one portable Function.
|
|
3903
3975
|
Loop over input array:
|
|
3904
|
-
→ Add recordInput: { items: [{ id: "1" }, { id: "2" }] } and
|
|
3976
|
+
→ Add recordInput: { items: [{ id: "1" }, { id: "2" }] } and call
|
|
3977
|
+
ctx.each(ctx.sampleInput.items, async (item, index) => { ... })
|
|
3905
3978
|
→ Use unique step tags per iteration (e.g. "process-" + item.id)
|
|
3979
|
+
→ map/filter/find/indexing on ctx.sampleInput are compile-time graph discovery only.
|
|
3980
|
+
→ Runtime-sized map/filter/find/some/every and arbitrary loops belong in a registered portable
|
|
3981
|
+
Function invoked through ctx.functions; never guess or freeze their results during recording.
|
|
3906
3982
|
Switch/if-else on feature input values:
|
|
3907
|
-
→
|
|
3908
|
-
→
|
|
3983
|
+
→ Prefer ctx.branch(ctx.when.eq(ctx.input.type, "a"), { then, else }).
|
|
3984
|
+
→ recordScenarios is for legacy compile-time graph discovery, not a runtime branch primitive.
|
|
3985
|
+
|
|
3986
|
+
SAFE COPY-READY PATTERNS:
|
|
3987
|
+
Runtime input branch:
|
|
3988
|
+
await ctx.branch(ctx.when.eq(ctx.input.kind, "refund"), {
|
|
3989
|
+
then: () => ctx.step("refund", () => ctx.api.run({ app, action: "refund", input: {...} })),
|
|
3990
|
+
else: () => ctx.step("charge", () => ctx.api.run({ app, action: "charge", input: {...} })),
|
|
3991
|
+
});
|
|
3992
|
+
Nested/indexed result check:
|
|
3993
|
+
await ctx.branch(ctx.when.eq(search.data.length, 0), { then: ..., else: ... });
|
|
3994
|
+
Compound condition:
|
|
3995
|
+
await ctx.branch(ctx.when.and(
|
|
3996
|
+
ctx.when.eq(result.status, "ready"),
|
|
3997
|
+
ctx.when.gt(result.count, 0),
|
|
3998
|
+
), { then: ..., else: ... });
|
|
3999
|
+
Runtime payment/reference string (never frozen at sync time):
|
|
4000
|
+
const reference = ctx.transform.concat(
|
|
4001
|
+
"pay_", ctx.transform.now(), "_", ctx.transform.uuid(),
|
|
4002
|
+
);
|
|
4003
|
+
await ctx.step("charge", () => ctx.fallback.execute({
|
|
4004
|
+
fallback: "charge-payment", input: { reference, ... },
|
|
4005
|
+
}));
|
|
4006
|
+
Fixed graph expansion:
|
|
4007
|
+
recordInput: { regions: ["ng", "gh"] },
|
|
4008
|
+
handler: async (ctx) => ctx.each(ctx.sampleInput.regions, async (region, index) => {
|
|
4009
|
+
await ctx.step("sync-region-" + index, () => ctx.functions.invoke(syncFn, "run", { region }));
|
|
4010
|
+
});
|
|
4011
|
+
|
|
4012
|
+
UNSAFE — NEVER GENERATE:
|
|
4013
|
+
if (result.count === 0) await ctx.step(...);
|
|
4014
|
+
const customer = found[0] ?? await ctx.step(...);
|
|
4015
|
+
ctx.input.items.map(item => ctx.step(...));
|
|
4016
|
+
for (const item of ctx.input.items) await ctx.step(...);
|
|
4017
|
+
const reference = "pay_" + Date.now() + "_" + Math.random();
|
|
4018
|
+
|
|
4019
|
+
BEFORE SYNCING A FEATURE:
|
|
4020
|
+
→ Confirm every runtime decision uses ctx.branch + ctx.when.
|
|
4021
|
+
→ Confirm every ctx.step tag is unique across both paths and every expanded iteration.
|
|
4022
|
+
→ Confirm no runtime proxy is consumed by native JavaScript control flow or array iteration.
|
|
4023
|
+
→ Confirm every ctx.step contains a portable ctx component/function call.
|
|
4024
|
+
→ Compile locally, inspect schema.steps, and verify both branch paths, condition, depends_on,
|
|
4025
|
+
and operator-valued inputs are present before persisting.
|
|
3909
4026
|
|
|
3910
4027
|
STEP 8 — SET rollbacks for reversible steps
|
|
3911
4028
|
Any step that allocates a resource should undo it if a later step fails.
|
|
@@ -4015,22 +4132,36 @@ Feature statuses: pending | running | completed | failed | rolled_back | rolling
|
|
|
4015
4132
|
|
|
4016
4133
|
━━━ FEATURE RECORDING SEMANTICS ━━━
|
|
4017
4134
|
|
|
4018
|
-
When you call features.define({ handler }), the handler
|
|
4135
|
+
When you call features.define({ handler }), there are two distinct phases, but the handler itself
|
|
4136
|
+
runs only during compilation/recording:
|
|
4019
4137
|
|
|
4020
4138
|
1. RECORDING PHASE (at define time) — handler is called with a RecordingContext.
|
|
4021
4139
|
All ctx.step() calls return lightweight proxy objects, not real data.
|
|
4022
4140
|
This phase captures the step graph: which steps exist, their types, tags, and declared
|
|
4023
4141
|
inputs/outputs. No real API calls, DB queries, or side effects occur.
|
|
4024
4142
|
Arbitrary JS code OUTSIDE ctx.step() ALSO runs during recording — with proxy values.
|
|
4025
|
-
For loops: supply recordInput and
|
|
4143
|
+
For loops: supply recordInput and use ctx.each(ctx.sampleInput.items, ...) so all iterations are recorded.
|
|
4026
4144
|
ctx.input is always the runtime operator surface and must never expose recordInput literals.
|
|
4027
|
-
For branches: use
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
ctx.
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4145
|
+
For branches: use ctx.branch(ctx.when.*, { then, else }) so both paths are captured. Use
|
|
4146
|
+
branchOverrides only for compatibility with existing Feature handlers.
|
|
4147
|
+
Never make an authorization, validation, tenancy, or other security decision by branching on
|
|
4148
|
+
ctx.input during recording. Use ctx.sampleInput only to discover graph shape; enforce security
|
|
4149
|
+
invariants inside a runtime portable Function or recorded step.
|
|
4150
|
+
|
|
4151
|
+
ductape features sync [filter] sets DUCTAPE_SYNC_MODE=1 and, when filtered,
|
|
4152
|
+
DUCTAPE_FEATURE_FILTER=<filter>. This is an administrative catalogue-only lifecycle: framework
|
|
4153
|
+
integrations and project readiness hooks must not start HTTP listeners, provider probes,
|
|
4154
|
+
schedulers, or Event consumers. Apply the filter before booting unrelated service modules.
|
|
4155
|
+
|
|
4156
|
+
2. EXECUTION PHASE (at runtime) — the stored schema.steps graph is interpreted by FeatureExecutor.
|
|
4157
|
+
The original JavaScript handler is NOT called. Step inputs and conditions resolve operators
|
|
4158
|
+
such as $Input{}, $Sequence{}, $Step{}, and $Now against runtime state. Only recorded portable
|
|
4159
|
+
component/function operations execute.
|
|
4160
|
+
|
|
4161
|
+
Implication: arbitrary JavaScript control flow never becomes runtime behavior merely because it
|
|
4162
|
+
appears in the handler. Express runtime branches through ctx.branch/ctx.when, fixed graph expansion
|
|
4163
|
+
through ctx.each(ctx.sampleInput...), and runtime-sized algorithms through ctx.functions. Put all
|
|
4164
|
+
meaningful business logic INSIDE recorded portable operations, not in the
|
|
4034
4165
|
outer handler body. Code in the outer body runs during recording with proxy values and
|
|
4035
4166
|
may behave unexpectedly (e.g. typeof proxy === 'object' is true but .someField is a proxy).
|
|
4036
4167
|
|
|
@@ -5100,8 +5231,10 @@ EXACT CODE-FIRST VECTOR CONTEXT:
|
|
|
5100
5231
|
ductape vector actions get <action-tag> --vector <vector-tag> --json
|
|
5101
5232
|
Always list and inspect first. Reuse an existing action when operation, namespace/filter/template,
|
|
5102
5233
|
parameters, and output semantics match; do not create a duplicate action under a new name.
|
|
5103
|
-
Update/delete/list use the same \`ductape vector actions\` surface.
|
|
5104
|
-
\`ductape.vector.
|
|
5234
|
+
Update/delete/list use the same plural \`ductape vector actions\` CLI surface. Runtime SDK/MCP calls
|
|
5235
|
+
use the singular \`ductape.vector.action.*\` namespace; execute saved actions with
|
|
5236
|
+
\`ductape.vector.action.execute({ product, env, vector, action, input })\`. Feature handlers instead
|
|
5237
|
+
use \`ctx.vector.execute({ vector, action, input })\` because product/env/session are inherited.
|
|
5105
5238
|
Vertex AI Vector Search stores and searches supplied vectors. It does NOT generate embeddings.
|
|
5106
5239
|
Do not claim that a Vertex Vector Search index embeds text.
|
|
5107
5240
|
|
|
@@ -5461,7 +5594,9 @@ const cliInputSchema = z.object({
|
|
|
5461
5594
|
'"features sync" (runs the project\'s own "features:sync" npm script) — never call ' +
|
|
5462
5595
|
'features.define from the app\'s normal startup path, since that blocks every boot on ' +
|
|
5463
5596
|
'Ductape API reachability. See ductape_docs for the full convention.\n\n' +
|
|
5464
|
-
'The CLI uses the user\'s local logged-in session
|
|
5597
|
+
'The CLI uses the user\'s local logged-in session. Prefer browser OAuth in a trusted local terminal: ' +
|
|
5598
|
+
'ductape login --browser google (or github). It returns automatically through a validated loopback callback. ' +
|
|
5599
|
+
'Never invoke interactive login through MCP or ask the user for credentials.'),
|
|
5465
5600
|
});
|
|
5466
5601
|
async function loadMcpSdk() {
|
|
5467
5602
|
try {
|
|
@@ -5626,6 +5761,25 @@ async function main() {
|
|
|
5626
5761
|
const isLocalMigrationGuidance = (firstWord === 'migrate-codebase' && !args.command.includes('--ensure-product')) ||
|
|
5627
5762
|
firstWord.startsWith('migration-');
|
|
5628
5763
|
const isDiagnostic = firstWord === 'doctor';
|
|
5764
|
+
if (firstWord === 'login') {
|
|
5765
|
+
return {
|
|
5766
|
+
content: [{
|
|
5767
|
+
type: 'text',
|
|
5768
|
+
text: [
|
|
5769
|
+
'Ductape login must be completed by the user in a trusted local terminal, not through an MCP tool process.',
|
|
5770
|
+
'',
|
|
5771
|
+
'Preferred browser OAuth:',
|
|
5772
|
+
' ductape login --browser google',
|
|
5773
|
+
' ductape login --browser github',
|
|
5774
|
+
'',
|
|
5775
|
+
'The browser returns to the CLI automatically through a validated 127.0.0.1 callback; no token copying is required.',
|
|
5776
|
+
'Never ask the user to paste a password, OAuth callback token, auth token, or stored CLI credential into the agent.',
|
|
5777
|
+
'After login succeeds, retry the original ductape_cli operation. The MCP will detect the new session.',
|
|
5778
|
+
].join('\n'),
|
|
5779
|
+
}],
|
|
5780
|
+
isError: true,
|
|
5781
|
+
};
|
|
5782
|
+
}
|
|
5629
5783
|
if (!isAuthCommand && !isLocalMigrationGuidance && !isDiagnostic) {
|
|
5630
5784
|
// Cache successful authentication, but re-check a missing/expired session on every call.
|
|
5631
5785
|
// The user may complete `ductape login` in another terminal while this MCP process remains
|
|
@@ -5648,6 +5802,7 @@ async function main() {
|
|
|
5648
5802
|
'or:',
|
|
5649
5803
|
` ductape login --browser google${wsFlag}`,
|
|
5650
5804
|
` ductape login --browser github${wsFlag}`,
|
|
5805
|
+
'Browser OAuth returns to the CLI automatically through a validated 127.0.0.1 callback.',
|
|
5651
5806
|
'',
|
|
5652
5807
|
'Never ask the user to paste their password, OAuth callback token, or stored CLI credential into the agent.',
|
|
5653
5808
|
'After login succeeds, retry the original ductape_cli command.',
|
|
@@ -6082,7 +6237,7 @@ async function main() {
|
|
|
6082
6237
|
'index strategy, operation types) that should be confirmed with the user first.\n\n' +
|
|
6083
6238
|
'Available topics: transactions, presave, triggers, aggregations, migrations, indexes, performance, actions, ' +
|
|
6084
6239
|
'graphs, storage, cloud, vector, warehouse, secrets, apps, products, sessions, caches, ' +
|
|
6085
|
-
'notifications, resilience, features, portable-functions, events, logs, migration, frontend, frontend-analytics, client, react, vue',
|
|
6240
|
+
'notifications, resilience, features, portable-functions, events, logs, migration, cli-authentication, frontend, frontend-analytics, client, react, vue',
|
|
6086
6241
|
inputSchema: docsInputSchema,
|
|
6087
6242
|
}, docsHandler);
|
|
6088
6243
|
server.registerTool('ductape_events_discover', {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ductape/mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.32",
|
|
4
4
|
"description": "MCP server that exposes Ductape SDK operations via the backend proxy",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
17
|
"build": "tsc",
|
|
18
|
-
"test": "npm run build && node scripts/check-cli-command-security.mjs && node scripts/check-frontend-analytics-guidance.mjs && node scripts/check-events-discovery.mjs && node scripts/check-schema-fallback.mjs && node scripts/check-paystack-action-schema.mjs && node scripts/check-portable-functions.mjs && node scripts/check-project-link-guidance.mjs && node scripts/check-graph-vector-projection-guidance.mjs && node scripts/check-asset-file-guidance.mjs",
|
|
18
|
+
"test": "npm run build && node scripts/check-cli-command-security.mjs && node scripts/check-frontend-analytics-guidance.mjs && node scripts/check-events-discovery.mjs && node scripts/check-schema-fallback.mjs && node scripts/check-paystack-action-schema.mjs && node scripts/check-portable-functions.mjs && node scripts/check-feature-control-flow.mjs && node scripts/check-project-link-guidance.mjs && node scripts/check-graph-vector-projection-guidance.mjs && node scripts/check-asset-file-guidance.mjs",
|
|
19
19
|
"start": "node dist/index.js",
|
|
20
20
|
"dev": "tsx src/index.ts"
|
|
21
21
|
},
|