@dypai-ai/mcp 1.3.0 → 1.3.1
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/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -817,7 +817,7 @@ async function handleRequest(msg) {
|
|
|
817
817
|
return makeResponse(id, {
|
|
818
818
|
protocolVersion: "2024-11-05",
|
|
819
819
|
capabilities: { tools: {} },
|
|
820
|
-
serverInfo: { name: "dypai", version: "1.3.
|
|
820
|
+
serverInfo: { name: "dypai", version: "1.3.1" },
|
|
821
821
|
instructions: SERVER_INSTRUCTIONS,
|
|
822
822
|
})
|
|
823
823
|
}
|
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
import { proxyToolCall } from "../proxy.js"
|
|
13
13
|
|
|
14
14
|
async function execSql(projectId, sql) {
|
|
15
|
-
|
|
15
|
+
// Bypass remote execute_sql auto-LIMIT 20 so describe counts match reality.
|
|
16
|
+
const hasLimit = /\bLIMIT\b/i.test(sql)
|
|
17
|
+
const finalSql = hasLimit ? sql : `${sql.replace(/;?\s*$/, "")} LIMIT 100000`
|
|
18
|
+
const args = projectId ? { project_id: projectId, sql: finalSql } : { sql: finalSql }
|
|
16
19
|
const result = await proxyToolCall("execute_sql", args)
|
|
17
20
|
if (result?.error) return null
|
|
18
21
|
if (!result?.rows) return null
|
|
@@ -54,7 +57,6 @@ export const dypaiDescribeTool = {
|
|
|
54
57
|
jsonb_array_length(e.workflow_code->'nodes') AS node_count
|
|
55
58
|
FROM system.endpoints e
|
|
56
59
|
LEFT JOIN system.endpoints_group g ON g.id = e.group_id
|
|
57
|
-
WHERE e.is_active = true
|
|
58
60
|
ORDER BY e.name
|
|
59
61
|
`),
|
|
60
62
|
execSql(project_id, "SELECT name, type FROM system.credentials ORDER BY name"),
|
|
@@ -17,7 +17,13 @@ import { deserializeEndpoint, serializeEndpoint } from "./codec.js"
|
|
|
17
17
|
// ─── Remote ────────────────────────────────────────────────────────────────
|
|
18
18
|
|
|
19
19
|
async function execSql(projectId, sql) {
|
|
20
|
-
|
|
20
|
+
// Bypass the remote execute_sql safety that injects `LIMIT 20` when no LIMIT
|
|
21
|
+
// is present. Planner needs the FULL endpoint/credential/group lists to
|
|
22
|
+
// compute an accurate diff — truncation here would mean invisible deletes
|
|
23
|
+
// (local thinks "remote has only X" when it actually has X+N).
|
|
24
|
+
const hasLimit = /\bLIMIT\b/i.test(sql)
|
|
25
|
+
const finalSql = hasLimit ? sql : `${sql.replace(/;?\s*$/, "")} LIMIT 100000`
|
|
26
|
+
const args = projectId ? { project_id: projectId, sql: finalSql } : { sql: finalSql }
|
|
21
27
|
const result = await proxyToolCall("execute_sql", args)
|
|
22
28
|
if (result?.error) throw new Error(`SQL error: ${result.error}`)
|
|
23
29
|
if (!result?.rows) throw new Error(`Unexpected SQL response: ${JSON.stringify(result).slice(0, 300)}`)
|
|
@@ -116,9 +122,8 @@ export async function fetchRemoteState(projectId) {
|
|
|
116
122
|
const [endpoints, credentials, groups] = await Promise.all([
|
|
117
123
|
execSql(projectId, `
|
|
118
124
|
SELECT id, name, method, description, workflow_code, input, output,
|
|
119
|
-
allowed_roles, is_tool, tool_description, group_id, updated_at
|
|
125
|
+
allowed_roles, is_tool, tool_description, group_id, is_active, updated_at
|
|
120
126
|
FROM system.endpoints
|
|
121
|
-
WHERE is_active = true
|
|
122
127
|
ORDER BY name
|
|
123
128
|
`),
|
|
124
129
|
execSql(projectId, "SELECT id, name, type FROM system.credentials"),
|
package/src/tools/sync/pull.js
CHANGED
|
@@ -441,7 +441,15 @@ workflow:
|
|
|
441
441
|
`
|
|
442
442
|
|
|
443
443
|
async function execSql(projectId, sql) {
|
|
444
|
-
|
|
444
|
+
// The remote `execute_sql` silently injects `LIMIT 20` whenever a query has no
|
|
445
|
+
// LIMIT of its own — intended as a guard against ad-hoc queries returning
|
|
446
|
+
// gigantic result sets. For pull we want the COMPLETE lists of endpoints,
|
|
447
|
+
// credentials, groups, realtime policies, etc. Without an explicit LIMIT
|
|
448
|
+
// here, a project with >20 of any resource would silently lose rows.
|
|
449
|
+
// We append a generous cap (100k) only when the caller didn't specify one.
|
|
450
|
+
const hasLimit = /\bLIMIT\b/i.test(sql)
|
|
451
|
+
const finalSql = hasLimit ? sql : `${sql.replace(/;?\s*$/, "")} LIMIT 100000`
|
|
452
|
+
const args = projectId ? { project_id: projectId, sql: finalSql } : { sql: finalSql }
|
|
445
453
|
const result = await proxyToolCall("execute_sql", args)
|
|
446
454
|
if (result?.error) throw new Error(`SQL error: ${result.error}`)
|
|
447
455
|
if (!result?.rows) {
|
|
@@ -553,9 +561,8 @@ export const dypaiPullTool = {
|
|
|
553
561
|
const [endpoints, credentials, groups, schemaSql, nodeCatalogResult, realtimePolicies] = await Promise.all([
|
|
554
562
|
execSql(project_id, `
|
|
555
563
|
SELECT id, name, method, description, workflow_code, input, output,
|
|
556
|
-
allowed_roles, is_tool, tool_description, group_id, updated_at
|
|
564
|
+
allowed_roles, is_tool, tool_description, group_id, is_active, updated_at
|
|
557
565
|
FROM system.endpoints
|
|
558
|
-
WHERE is_active = true
|
|
559
566
|
ORDER BY name
|
|
560
567
|
`),
|
|
561
568
|
execSql(project_id, "SELECT id, name, type FROM system.credentials"),
|
|
@@ -650,7 +657,22 @@ export const dypaiPullTool = {
|
|
|
650
657
|
const relPath = groupName
|
|
651
658
|
? `endpoints/${groupName}/${row.name}.yaml`
|
|
652
659
|
: `endpoints/${row.name}.yaml`
|
|
653
|
-
|
|
660
|
+
|
|
661
|
+
// Inactive endpoints ARE pulled (user needs to see them), but flagged
|
|
662
|
+
// with a visible header so the agent/user knows the endpoint won't
|
|
663
|
+
// execute until re-enabled in the dashboard. `is_active` isn't
|
|
664
|
+
// serialized into the YAML itself — push only updates content, never
|
|
665
|
+
// the active flag, so editing + pushing an inactive endpoint keeps it
|
|
666
|
+
// inactive (safe default).
|
|
667
|
+
const yamlBody = renderYaml(doc)
|
|
668
|
+
const content = row.is_active === false
|
|
669
|
+
? "# ⚠️ INACTIVE on the engine — this endpoint will NOT execute until re-enabled in the dashboard.\n" +
|
|
670
|
+
"# Edits applied via `dypai_push` are still saved, but the endpoint stays paused.\n" +
|
|
671
|
+
"# To reactivate: go to the project dashboard → Endpoints → toggle this one back on.\n\n" +
|
|
672
|
+
yamlBody
|
|
673
|
+
: yamlBody
|
|
674
|
+
|
|
675
|
+
await writeFileEnsured(join(outDir, relPath), content)
|
|
654
676
|
filesWritten.push(relPath)
|
|
655
677
|
} catch (e) {
|
|
656
678
|
errors.push({ endpoint: row.name, error: e.message })
|
|
@@ -730,6 +752,9 @@ export const dypaiPullTool = {
|
|
|
730
752
|
const toolEndpoints = (endpoints || [])
|
|
731
753
|
.filter(e => e.is_tool)
|
|
732
754
|
.map(e => ({ name: e.name, description: e.tool_description || null }))
|
|
755
|
+
const inactiveEndpoints = (endpoints || [])
|
|
756
|
+
.filter(e => e.is_active === false)
|
|
757
|
+
.map(e => e.name)
|
|
733
758
|
|
|
734
759
|
const overview = {
|
|
735
760
|
project: projectInfo ? {
|
|
@@ -739,9 +764,12 @@ export const dypaiPullTool = {
|
|
|
739
764
|
} : { id: resolvedProjectId || "(from token)" },
|
|
740
765
|
endpoints: {
|
|
741
766
|
total: (endpoints || []).length,
|
|
767
|
+
active: (endpoints || []).filter(e => e.is_active !== false).length,
|
|
768
|
+
inactive: inactiveEndpoints.length,
|
|
742
769
|
groups: Object.keys(byGroup).filter(g => g !== "(no group)").sort(),
|
|
743
770
|
by_group: byGroup,
|
|
744
771
|
tool_endpoints: toolEndpoints,
|
|
772
|
+
inactive_endpoints: inactiveEndpoints.length > 0 ? inactiveEndpoints : undefined,
|
|
745
773
|
},
|
|
746
774
|
credentials: (credentials || []).map(c => ({ name: c.name, type: c.type })),
|
|
747
775
|
realtime_policies: (realtimePolicies || []).length,
|
|
@@ -7,7 +7,13 @@
|
|
|
7
7
|
import { proxyToolCall } from "../proxy.js"
|
|
8
8
|
|
|
9
9
|
async function execSql(projectId, sql) {
|
|
10
|
-
|
|
10
|
+
// Bypass remote execute_sql auto-LIMIT 20 so the schema dump is complete.
|
|
11
|
+
// Without this, a project with >20 columns across public.* (very normal)
|
|
12
|
+
// would produce a truncated schema.sql silently — breaks the validator and
|
|
13
|
+
// any agent that reads schema.sql before writing SQL.
|
|
14
|
+
const hasLimit = /\bLIMIT\b/i.test(sql)
|
|
15
|
+
const finalSql = hasLimit ? sql : `${sql.replace(/;?\s*$/, "")} LIMIT 100000`
|
|
16
|
+
const args = projectId ? { project_id: projectId, sql: finalSql } : { sql: finalSql }
|
|
11
17
|
const result = await proxyToolCall("execute_sql", args)
|
|
12
18
|
if (result?.error) throw new Error(`SQL error: ${result.error}`)
|
|
13
19
|
if (!result?.rows) throw new Error(`Unexpected SQL response: ${JSON.stringify(result).slice(0, 300)}`)
|