@ductape/mcp 0.2.30 → 0.2.31
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 +79 -15
- package/package.json +1 -1
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
|
|
@@ -1500,6 +1501,7 @@ function runCli(command) {
|
|
|
1500
1501
|
'or use an OAuth flow:',
|
|
1501
1502
|
' ductape login --browser google',
|
|
1502
1503
|
' ductape login --browser github',
|
|
1504
|
+
'Browser OAuth returns to the CLI automatically through a validated 127.0.0.1 callback.',
|
|
1503
1505
|
'',
|
|
1504
1506
|
'Do not paste a password, OAuth callback token, or stored CLI credential into an agent prompt.',
|
|
1505
1507
|
'After login succeeds, retry the same ductape_cli command.',
|
|
@@ -1551,7 +1553,7 @@ const docsInputSchema = z.object({
|
|
|
1551
1553
|
topic: z.string().describe('Feature topic to look up. Supported: ' +
|
|
1552
1554
|
'transactions, presave, triggers, aggregations, migrations, indexes, performance, actions, ' +
|
|
1553
1555
|
'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'),
|
|
1556
|
+
'notifications, resilience, features, portable-functions, events, logs, migration, cli-authentication, frontend, frontend-analytics, client, react, vue'),
|
|
1555
1557
|
});
|
|
1556
1558
|
const eventsDiscoveryInputSchema = z.object({
|
|
1557
1559
|
query: z.string().optional().describe('Capability or recovery search, including DLQ, dead letter, failed messages, retry, poison message, replay, or consumer failure.'),
|
|
@@ -1607,6 +1609,34 @@ const migrationInputSchema = z.object({
|
|
|
1607
1609
|
write: z.boolean().optional().default(false).describe('Write redacted advisory artifacts only. This never writes application code or executable Ductape assets.'),
|
|
1608
1610
|
});
|
|
1609
1611
|
const DOCS = {
|
|
1612
|
+
'cli-authentication': `
|
|
1613
|
+
DUCTAPE CLI AUTHENTICATION
|
|
1614
|
+
|
|
1615
|
+
For an interactive local login, prefer browser OAuth:
|
|
1616
|
+
ductape login --browser google
|
|
1617
|
+
ductape login --browser github
|
|
1618
|
+
|
|
1619
|
+
The CLI opens the provider in the user's browser, starts a temporary loopback listener on
|
|
1620
|
+
127.0.0.1, validates the returned OAuth state, exchanges the callback token, stores the resulting
|
|
1621
|
+
session in the local Ductape credential store, and then continues workspace selection. The user
|
|
1622
|
+
does not copy a callback token or share credentials with an agent.
|
|
1623
|
+
|
|
1624
|
+
Run browser login only in the user's trusted local terminal. An MCP tool, agent subprocess, CI
|
|
1625
|
+
runner, container, SSH session, or remote development host may not own the browser's loopback
|
|
1626
|
+
interface. Do not invoke interactive login through ductape_cli and do not ask the user to paste a
|
|
1627
|
+
password, OAuth callback token, auth token, or stored credential into chat.
|
|
1628
|
+
|
|
1629
|
+
Use email/password login only when the user deliberately chooses it in their own terminal:
|
|
1630
|
+
ductape login
|
|
1631
|
+
|
|
1632
|
+
Use --token only as a compatibility or automation fallback when the user already possesses a
|
|
1633
|
+
valid OAuth callback token through a trusted flow. Never solicit that token in an agent prompt.
|
|
1634
|
+
|
|
1635
|
+
After login succeeds, retry the original ductape_cli operation. The MCP re-reads a previously
|
|
1636
|
+
missing or expired external CLI session without requiring an MCP restart. If a command returns
|
|
1637
|
+
HTTP 401 while workspace reads still succeed, treat it as endpoint authorization or command
|
|
1638
|
+
routing failure, not as a reason to re-authenticate.
|
|
1639
|
+
`.trim(),
|
|
1610
1640
|
'portable-functions': `
|
|
1611
1641
|
PORTABLE APPLICATION FUNCTIONS
|
|
1612
1642
|
|
|
@@ -2551,10 +2581,12 @@ Schema management:
|
|
|
2551
2581
|
graph.dropIndex / dropConstraint / listIndexes / listConstraints
|
|
2552
2582
|
|
|
2553
2583
|
Saved actions (parameterized queries stored on the product):
|
|
2554
|
-
graph.
|
|
2555
|
-
graph.
|
|
2556
|
-
graph.
|
|
2557
|
-
graph.
|
|
2584
|
+
graph.action.create [{ product, graph|graphTag, name, description?, operation, query, parameters? }]
|
|
2585
|
+
graph.action.fetchAll [{ product, graph|graphTag }]
|
|
2586
|
+
graph.action.fetch [{ product, graph|graphTag, action|actionTag }]
|
|
2587
|
+
graph.action.execute [{ product, env, graph, action, input, session? }]
|
|
2588
|
+
graph.action.dispatch [{ product, env, graph, event, input, schedule? }] ← call ductape_generate_payload FIRST
|
|
2589
|
+
Use graph.action.execute for a saved action. graph.query is only for a direct provider-native query.
|
|
2558
2590
|
|
|
2559
2591
|
Supported index types: btree | fulltext | vector | range | point | text
|
|
2560
2592
|
Supported constraint types: UNIQUE | EXISTS | NODE_KEY
|
|
@@ -4025,6 +4057,14 @@ When you call features.define({ handler }), the handler runs TWICE:
|
|
|
4025
4057
|
For loops: supply recordInput and iterate ctx.sampleInput so all iterations are recorded.
|
|
4026
4058
|
ctx.input is always the runtime operator surface and must never expose recordInput literals.
|
|
4027
4059
|
For branches: use branchOverrides so each path is captured.
|
|
4060
|
+
Never make an authorization, validation, tenancy, or other security decision by branching on
|
|
4061
|
+
ctx.input during recording. Use ctx.sampleInput only to discover graph shape; enforce security
|
|
4062
|
+
invariants inside a runtime portable Function or recorded step.
|
|
4063
|
+
|
|
4064
|
+
ductape features sync [filter] sets DUCTAPE_SYNC_MODE=1 and, when filtered,
|
|
4065
|
+
DUCTAPE_FEATURE_FILTER=<filter>. This is an administrative catalogue-only lifecycle: framework
|
|
4066
|
+
integrations and project readiness hooks must not start HTTP listeners, provider probes,
|
|
4067
|
+
schedulers, or Event consumers. Apply the filter before booting unrelated service modules.
|
|
4028
4068
|
|
|
4029
4069
|
2. EXECUTION PHASE (at runtime) — handler is called with a real ExecutionContext.
|
|
4030
4070
|
ctx.step() actually executes. All real Ductape component calls happen.
|
|
@@ -5100,8 +5140,10 @@ EXACT CODE-FIRST VECTOR CONTEXT:
|
|
|
5100
5140
|
ductape vector actions get <action-tag> --vector <vector-tag> --json
|
|
5101
5141
|
Always list and inspect first. Reuse an existing action when operation, namespace/filter/template,
|
|
5102
5142
|
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.
|
|
5143
|
+
Update/delete/list use the same plural \`ductape vector actions\` CLI surface. Runtime SDK/MCP calls
|
|
5144
|
+
use the singular \`ductape.vector.action.*\` namespace; execute saved actions with
|
|
5145
|
+
\`ductape.vector.action.execute({ product, env, vector, action, input })\`. Feature handlers instead
|
|
5146
|
+
use \`ctx.vector.execute({ vector, action, input })\` because product/env/session are inherited.
|
|
5105
5147
|
Vertex AI Vector Search stores and searches supplied vectors. It does NOT generate embeddings.
|
|
5106
5148
|
Do not claim that a Vertex Vector Search index embeds text.
|
|
5107
5149
|
|
|
@@ -5461,7 +5503,9 @@ const cliInputSchema = z.object({
|
|
|
5461
5503
|
'"features sync" (runs the project\'s own "features:sync" npm script) — never call ' +
|
|
5462
5504
|
'features.define from the app\'s normal startup path, since that blocks every boot on ' +
|
|
5463
5505
|
'Ductape API reachability. See ductape_docs for the full convention.\n\n' +
|
|
5464
|
-
'The CLI uses the user\'s local logged-in session
|
|
5506
|
+
'The CLI uses the user\'s local logged-in session. Prefer browser OAuth in a trusted local terminal: ' +
|
|
5507
|
+
'ductape login --browser google (or github). It returns automatically through a validated loopback callback. ' +
|
|
5508
|
+
'Never invoke interactive login through MCP or ask the user for credentials.'),
|
|
5465
5509
|
});
|
|
5466
5510
|
async function loadMcpSdk() {
|
|
5467
5511
|
try {
|
|
@@ -5626,6 +5670,25 @@ async function main() {
|
|
|
5626
5670
|
const isLocalMigrationGuidance = (firstWord === 'migrate-codebase' && !args.command.includes('--ensure-product')) ||
|
|
5627
5671
|
firstWord.startsWith('migration-');
|
|
5628
5672
|
const isDiagnostic = firstWord === 'doctor';
|
|
5673
|
+
if (firstWord === 'login') {
|
|
5674
|
+
return {
|
|
5675
|
+
content: [{
|
|
5676
|
+
type: 'text',
|
|
5677
|
+
text: [
|
|
5678
|
+
'Ductape login must be completed by the user in a trusted local terminal, not through an MCP tool process.',
|
|
5679
|
+
'',
|
|
5680
|
+
'Preferred browser OAuth:',
|
|
5681
|
+
' ductape login --browser google',
|
|
5682
|
+
' ductape login --browser github',
|
|
5683
|
+
'',
|
|
5684
|
+
'The browser returns to the CLI automatically through a validated 127.0.0.1 callback; no token copying is required.',
|
|
5685
|
+
'Never ask the user to paste a password, OAuth callback token, auth token, or stored CLI credential into the agent.',
|
|
5686
|
+
'After login succeeds, retry the original ductape_cli operation. The MCP will detect the new session.',
|
|
5687
|
+
].join('\n'),
|
|
5688
|
+
}],
|
|
5689
|
+
isError: true,
|
|
5690
|
+
};
|
|
5691
|
+
}
|
|
5629
5692
|
if (!isAuthCommand && !isLocalMigrationGuidance && !isDiagnostic) {
|
|
5630
5693
|
// Cache successful authentication, but re-check a missing/expired session on every call.
|
|
5631
5694
|
// The user may complete `ductape login` in another terminal while this MCP process remains
|
|
@@ -5648,6 +5711,7 @@ async function main() {
|
|
|
5648
5711
|
'or:',
|
|
5649
5712
|
` ductape login --browser google${wsFlag}`,
|
|
5650
5713
|
` ductape login --browser github${wsFlag}`,
|
|
5714
|
+
'Browser OAuth returns to the CLI automatically through a validated 127.0.0.1 callback.',
|
|
5651
5715
|
'',
|
|
5652
5716
|
'Never ask the user to paste their password, OAuth callback token, or stored CLI credential into the agent.',
|
|
5653
5717
|
'After login succeeds, retry the original ductape_cli command.',
|
|
@@ -6082,7 +6146,7 @@ async function main() {
|
|
|
6082
6146
|
'index strategy, operation types) that should be confirmed with the user first.\n\n' +
|
|
6083
6147
|
'Available topics: transactions, presave, triggers, aggregations, migrations, indexes, performance, actions, ' +
|
|
6084
6148
|
'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',
|
|
6149
|
+
'notifications, resilience, features, portable-functions, events, logs, migration, cli-authentication, frontend, frontend-analytics, client, react, vue',
|
|
6086
6150
|
inputSchema: docsInputSchema,
|
|
6087
6151
|
}, docsHandler);
|
|
6088
6152
|
server.registerTool('ductape_events_discover', {
|