@ratio-mcp/dev-server 1.2.0 → 1.3.0
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/dist/data/scope-webhook-map.d.ts +26 -0
- package/dist/data/scope-webhook-map.d.ts.map +1 -0
- package/dist/data/scope-webhook-map.js +117 -0
- package/dist/data/scope-webhook-map.js.map +1 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -13
- package/dist/index.js.map +1 -1
- package/dist/orchestrated-index.d.ts +4 -9
- package/dist/orchestrated-index.d.ts.map +1 -1
- package/dist/orchestrated-index.js +6 -14
- package/dist/orchestrated-index.js.map +1 -1
- package/dist/orchestrated-server.d.ts +14 -9
- package/dist/orchestrated-server.d.ts.map +1 -1
- package/dist/orchestrated-server.js +86 -48
- package/dist/orchestrated-server.js.map +1 -1
- package/dist/services/session-state.d.ts +36 -16
- package/dist/services/session-state.d.ts.map +1 -1
- package/dist/services/session-state.js +175 -140
- package/dist/services/session-state.js.map +1 -1
- package/dist/services/tool-guard.d.ts +29 -9
- package/dist/services/tool-guard.d.ts.map +1 -1
- package/dist/services/tool-guard.js +76 -50
- package/dist/services/tool-guard.js.map +1 -1
- package/dist/templates/frontend/.env.example +1 -1
- package/dist/templates/frontend/src/pages/Login.tsx +1 -1
- package/dist/tools/codegen.d.ts.map +1 -1
- package/dist/tools/codegen.js +206 -10
- package/dist/tools/codegen.js.map +1 -1
- package/dist/tools/get-status.d.ts +3 -0
- package/dist/tools/get-status.d.ts.map +1 -0
- package/dist/tools/get-status.js +127 -0
- package/dist/tools/get-status.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/lifecycle.js +1 -1
- package/dist/tools/lifecycle.js.map +1 -1
- package/dist/tools/requirements.d.ts.map +1 -1
- package/dist/tools/requirements.js +41 -4
- package/dist/tools/requirements.js.map +1 -1
- package/dist/tools/scaffold.d.ts.map +1 -1
- package/dist/tools/scaffold.js +10 -5
- package/dist/tools/scaffold.js.map +1 -1
- package/dist/tools/webhooks.d.ts +25 -0
- package/dist/tools/webhooks.d.ts.map +1 -1
- package/dist/tools/webhooks.js +115 -89
- package/dist/tools/webhooks.js.map +1 -1
- package/dist/utils/logger.js +17 -17
- package/dist/utils/logger.js.map +1 -1
- package/package.json +16 -15
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope → Webhook Event Recommendations
|
|
3
|
+
*
|
|
4
|
+
* Maps confirmed OAuth scopes to relevant webhook events.
|
|
5
|
+
* Used after define_app_requirements to suggest which webhooks
|
|
6
|
+
* the developer should subscribe to based on their selected scopes.
|
|
7
|
+
*
|
|
8
|
+
* Events are sourced from docs-server/schemas/webhooks.json.
|
|
9
|
+
*/
|
|
10
|
+
export interface WebhookRecommendation {
|
|
11
|
+
topic: string;
|
|
12
|
+
description: string;
|
|
13
|
+
resource: string;
|
|
14
|
+
/** Why this event is relevant given the scope */
|
|
15
|
+
reason: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get recommended webhook events based on confirmed scopes.
|
|
19
|
+
* Deduplicates events when multiple scopes map to the same resource.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getWebhookRecommendations(scopes: string[]): {
|
|
22
|
+
recommendations: WebhookRecommendation[];
|
|
23
|
+
scopes_matched: string[];
|
|
24
|
+
scopes_without_webhooks: string[];
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=scope-webhook-map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-webhook-map.d.ts","sourceRoot":"","sources":["../../src/data/scope-webhook-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;CAChB;AA4ED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG;IAC3D,eAAe,EAAE,qBAAqB,EAAE,CAAC;IACzC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,uBAAuB,EAAE,MAAM,EAAE,CAAC;CACnC,CAkCA"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope → Webhook Event Recommendations
|
|
3
|
+
*
|
|
4
|
+
* Maps confirmed OAuth scopes to relevant webhook events.
|
|
5
|
+
* Used after define_app_requirements to suggest which webhooks
|
|
6
|
+
* the developer should subscribe to based on their selected scopes.
|
|
7
|
+
*
|
|
8
|
+
* Events are sourced from docs-server/schemas/webhooks.json.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Map of scope → recommended webhook events.
|
|
12
|
+
* Write scopes inherit their read scope's events.
|
|
13
|
+
*/
|
|
14
|
+
const SCOPE_WEBHOOK_MAP = {
|
|
15
|
+
read_orders: [
|
|
16
|
+
{
|
|
17
|
+
topic: 'orders/create',
|
|
18
|
+
description: 'Fired when a new order is created',
|
|
19
|
+
resource: 'orders',
|
|
20
|
+
reason: 'React to new orders in real-time instead of polling',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
topic: 'orders/updated',
|
|
24
|
+
description: 'Fired when an order is updated',
|
|
25
|
+
resource: 'orders',
|
|
26
|
+
reason: 'Track order status changes (shipping, notes, etc.)',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
topic: 'orders/cancelled',
|
|
30
|
+
description: 'Fired when an order is cancelled',
|
|
31
|
+
resource: 'orders',
|
|
32
|
+
reason: 'Handle cancellations immediately (refunds, inventory)',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
topic: 'orders/fulfilled',
|
|
36
|
+
description: 'Fired when an order is fulfilled',
|
|
37
|
+
resource: 'orders',
|
|
38
|
+
reason: 'Trigger post-fulfillment workflows (emails, analytics)',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
topic: 'orders/paid',
|
|
42
|
+
description: 'Fired when an order is paid',
|
|
43
|
+
resource: 'orders',
|
|
44
|
+
reason: 'Track payment completions for revenue reporting',
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
read_products: [
|
|
48
|
+
{
|
|
49
|
+
topic: 'products/create',
|
|
50
|
+
description: 'Fired when a new product is created',
|
|
51
|
+
resource: 'products',
|
|
52
|
+
reason: 'Sync new products to external catalogs or feeds',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
topic: 'products/update',
|
|
56
|
+
description: 'Fired when a product is updated',
|
|
57
|
+
resource: 'products',
|
|
58
|
+
reason: 'Keep product data in sync (price changes, stock updates)',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
topic: 'products/delete',
|
|
62
|
+
description: 'Fired when a product is deleted',
|
|
63
|
+
resource: 'products',
|
|
64
|
+
reason: 'Remove deleted products from external systems',
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
// Write scopes inherit read scope events
|
|
69
|
+
SCOPE_WEBHOOK_MAP['write_orders'] = SCOPE_WEBHOOK_MAP['read_orders'];
|
|
70
|
+
SCOPE_WEBHOOK_MAP['write_products'] = SCOPE_WEBHOOK_MAP['read_products'];
|
|
71
|
+
/** Always-recommended events regardless of scopes */
|
|
72
|
+
const ALWAYS_RECOMMENDED = [
|
|
73
|
+
{
|
|
74
|
+
topic: 'app/uninstalled',
|
|
75
|
+
description: 'Fired when the app is uninstalled by a merchant',
|
|
76
|
+
resource: 'app',
|
|
77
|
+
reason: 'Clean up merchant data and revoke tokens when uninstalled',
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
/**
|
|
81
|
+
* Get recommended webhook events based on confirmed scopes.
|
|
82
|
+
* Deduplicates events when multiple scopes map to the same resource.
|
|
83
|
+
*/
|
|
84
|
+
export function getWebhookRecommendations(scopes) {
|
|
85
|
+
const seen = new Set();
|
|
86
|
+
const recommendations = [];
|
|
87
|
+
const scopesMatched = [];
|
|
88
|
+
const scopesWithout = [];
|
|
89
|
+
for (const scope of scopes) {
|
|
90
|
+
const events = SCOPE_WEBHOOK_MAP[scope];
|
|
91
|
+
if (events) {
|
|
92
|
+
scopesMatched.push(scope);
|
|
93
|
+
for (const event of events) {
|
|
94
|
+
if (!seen.has(event.topic)) {
|
|
95
|
+
seen.add(event.topic);
|
|
96
|
+
recommendations.push(event);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
scopesWithout.push(scope);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Always add app/uninstalled
|
|
105
|
+
for (const event of ALWAYS_RECOMMENDED) {
|
|
106
|
+
if (!seen.has(event.topic)) {
|
|
107
|
+
seen.add(event.topic);
|
|
108
|
+
recommendations.push(event);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
recommendations,
|
|
113
|
+
scopes_matched: scopesMatched,
|
|
114
|
+
scopes_without_webhooks: scopesWithout,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=scope-webhook-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-webhook-map.js","sourceRoot":"","sources":["../../src/data/scope-webhook-map.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Ratio Dev MCP Server — Entry Point
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Tool-first architecture: exposes all tools individually with prerequisite guards.
|
|
6
|
+
* The LLM decides what to call; guards enforce the dependency graph.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Modes:
|
|
9
|
+
* Default: Tool-first server (all tools with guards)
|
|
10
|
+
* RATIO_STANDALONE_MODE=true: Standalone server (all tools, no orchestration)
|
|
10
11
|
*/
|
|
11
12
|
export {};
|
|
12
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG"}
|
package/dist/index.js
CHANGED
|
@@ -2,43 +2,41 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Ratio Dev MCP Server — Entry Point
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Tool-first architecture: exposes all tools individually with prerequisite guards.
|
|
6
|
+
* The LLM decides what to call; guards enforce the dependency graph.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Modes:
|
|
9
|
+
* Default: Tool-first server (all tools with guards)
|
|
10
|
+
* RATIO_STANDALONE_MODE=true: Standalone server (all tools, no orchestration)
|
|
10
11
|
*/
|
|
11
12
|
// Load .env BEFORE any other imports so process.env is populated
|
|
12
|
-
// Must use dynamic imports to ensure dotenv runs before constants.ts is evaluated
|
|
13
13
|
import { config } from 'dotenv';
|
|
14
14
|
import { resolve, dirname } from 'path';
|
|
15
15
|
import { fileURLToPath } from 'url';
|
|
16
16
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
17
|
-
// __dirname = dist/ → go up to: dev-server/ → packages/ → ratio-mcp-v2/
|
|
18
17
|
const envPath = resolve(__dirname, '..', '..', '..', '.env');
|
|
19
18
|
config({ path: envPath });
|
|
20
19
|
async function main() {
|
|
21
|
-
// Dynamic imports — these run AFTER dotenv has loaded env vars
|
|
22
20
|
const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
|
|
23
21
|
const { createOrchestratedServer } = await import('./orchestrated-server.js');
|
|
24
22
|
const { createDevServer } = await import('./server.js');
|
|
25
23
|
const { logger } = await import('./utils/logger.js');
|
|
26
|
-
const
|
|
24
|
+
const standaloneMode = process.env.RATIO_STANDALONE_MODE === 'true';
|
|
27
25
|
logger.info(`Loaded .env from: ${envPath}`);
|
|
28
26
|
logger.info(`RATIO_API_BASE_URL = ${process.env.RATIO_API_BASE_URL || '(not set, using default)'}`);
|
|
29
|
-
if (
|
|
30
|
-
logger.info('Starting Ratio Dev MCP Server (
|
|
27
|
+
if (standaloneMode) {
|
|
28
|
+
logger.info('Starting Ratio Dev MCP Server (Standalone Mode)...');
|
|
31
29
|
const server = createDevServer();
|
|
32
30
|
const transport = new StdioServerTransport();
|
|
33
31
|
await server.connect(transport);
|
|
34
|
-
logger.info('Ratio Dev MCP Server (
|
|
32
|
+
logger.info('Ratio Dev MCP Server (Standalone) is running on stdio');
|
|
35
33
|
}
|
|
36
34
|
else {
|
|
37
|
-
logger.info('Starting Ratio Dev MCP Server (
|
|
35
|
+
logger.info('Starting Ratio Dev MCP Server (Tool-First Architecture)...');
|
|
38
36
|
const server = createOrchestratedServer();
|
|
39
37
|
const transport = new StdioServerTransport();
|
|
40
38
|
await server.connect(transport);
|
|
41
|
-
logger.info('Ratio Dev MCP Server (
|
|
39
|
+
logger.info('Ratio Dev MCP Server (Tool-First) is running on stdio');
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
42
|
main().catch((error) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG;AAEH,iEAAiE;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAC7D,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAE1B,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,2CAA2C,CAAC,CAAC;IAC3F,MAAM,EAAE,wBAAwB,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;IAC9E,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACxD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAErD,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,MAAM,CAAC;IAEpE,MAAM,CAAC,IAAI,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAC;IAC5C,MAAM,CAAC,IAAI,CAAC,wBAAwB,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,0BAA0B,EAAE,CAAC,CAAC;IAEpG,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;IACvE,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;QAC1E,MAAM,MAAM,GAAG,wBAAwB,EAAE,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Ratio Dev MCP Server — Orchestrated Entry Point
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* correct tool is called at the right time in the right order.
|
|
5
|
+
* Tool-first architecture: exposes all tools individually with prerequisite guards.
|
|
6
|
+
* The LLM decides what to call; guards enforce the dependency graph.
|
|
8
7
|
*
|
|
9
|
-
*
|
|
10
|
-
* node dist/orchestrated-index.js
|
|
11
|
-
*
|
|
12
|
-
* Or via the bin alias:
|
|
13
|
-
* ratio-dev-orchestrated
|
|
8
|
+
* This is the production entry point.
|
|
14
9
|
*/
|
|
15
10
|
export {};
|
|
16
11
|
//# sourceMappingURL=orchestrated-index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrated-index.d.ts","sourceRoot":"","sources":["../src/orchestrated-index.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"orchestrated-index.d.ts","sourceRoot":"","sources":["../src/orchestrated-index.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG"}
|
|
@@ -1,38 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Ratio Dev MCP Server — Orchestrated Entry Point
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* correct tool is called at the right time in the right order.
|
|
5
|
+
* Tool-first architecture: exposes all tools individually with prerequisite guards.
|
|
6
|
+
* The LLM decides what to call; guards enforce the dependency graph.
|
|
8
7
|
*
|
|
9
|
-
*
|
|
10
|
-
* node dist/orchestrated-index.js
|
|
11
|
-
*
|
|
12
|
-
* Or via the bin alias:
|
|
13
|
-
* ratio-dev-orchestrated
|
|
8
|
+
* This is the production entry point.
|
|
14
9
|
*/
|
|
15
10
|
// Load .env BEFORE any other imports so process.env is populated
|
|
16
|
-
// Must use dynamic imports to ensure dotenv runs before constants.ts is evaluated
|
|
17
11
|
import { config } from 'dotenv';
|
|
18
12
|
import { resolve, dirname } from 'path';
|
|
19
13
|
import { fileURLToPath } from 'url';
|
|
20
14
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
21
|
-
// __dirname = dist/ → go up to: dev-server/ → packages/ → ratio-mcp-v2/
|
|
22
15
|
const envPath = resolve(__dirname, '..', '..', '..', '.env');
|
|
23
16
|
config({ path: envPath });
|
|
24
17
|
async function main() {
|
|
25
|
-
// Dynamic imports — these run AFTER dotenv has loaded env vars
|
|
26
18
|
const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
|
|
27
19
|
const { createOrchestratedServer } = await import('./orchestrated-server.js');
|
|
28
20
|
const { logger } = await import('./utils/logger.js');
|
|
29
21
|
logger.info(`Loaded .env from: ${envPath}`);
|
|
30
22
|
logger.info(`RATIO_API_BASE_URL = ${process.env.RATIO_API_BASE_URL || '(not set, using default)'}`);
|
|
31
|
-
logger.info('Starting Ratio Dev MCP Server (
|
|
23
|
+
logger.info('Starting Ratio Dev MCP Server (Tool-First Architecture)...');
|
|
32
24
|
const server = createOrchestratedServer();
|
|
33
25
|
const transport = new StdioServerTransport();
|
|
34
26
|
await server.connect(transport);
|
|
35
|
-
logger.info('Ratio Dev MCP Server (
|
|
27
|
+
logger.info('Ratio Dev MCP Server (Tool-First) is running on stdio');
|
|
36
28
|
}
|
|
37
29
|
main().catch((error) => {
|
|
38
30
|
console.error('Fatal error:', error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrated-index.js","sourceRoot":"","sources":["../src/orchestrated-index.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"orchestrated-index.js","sourceRoot":"","sources":["../src/orchestrated-index.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAEH,iEAAiE;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAC7D,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAE1B,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,2CAA2C,CAAC,CAAC;IAC3F,MAAM,EAAE,wBAAwB,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;IAC9E,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAErD,MAAM,CAAC,IAAI,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAC;IAC5C,MAAM,CAAC,IAAI,CAAC,wBAAwB,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,0BAA0B,EAAE,CAAC,CAAC;IACpG,MAAM,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;IAE1E,MAAM,MAAM,GAAG,wBAAwB,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;AACvE,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
/**
|
|
3
|
-
* Create the
|
|
3
|
+
* Create the Tool-First Ratio Dev MCP Server.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Exposes all tools individually (not a single agent_chat).
|
|
6
|
+
* Each tool call passes through the prerequisite guard.
|
|
7
|
+
* The LLM decides what to call based on user intent and get_status output.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* Guard enforcement:
|
|
10
|
+
* - If prerequisites are met → tool executes normally
|
|
11
|
+
* - If prerequisites are NOT met → returns structured error with:
|
|
12
|
+
* - What's missing
|
|
13
|
+
* - The full chain of tools needed to unblock
|
|
14
|
+
* - A hint for the LLM to self-correct
|
|
15
|
+
*
|
|
16
|
+
* Session recording:
|
|
17
|
+
* - On success, tool results are parsed to extract context (appId, scopes, etc.)
|
|
18
|
+
* - This context drives future guard checks
|
|
14
19
|
*/
|
|
15
20
|
export declare function createOrchestratedServer(): McpServer;
|
|
16
21
|
//# sourceMappingURL=orchestrated-server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrated-server.d.ts","sourceRoot":"","sources":["../src/orchestrated-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"orchestrated-server.d.ts","sourceRoot":"","sources":["../src/orchestrated-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,IAAI,SAAS,CAyFpD"}
|
|
@@ -1,63 +1,101 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { DEV_SERVER_NAME, DEV_SERVER_VERSION } from '@ratio-mcp/shared';
|
|
3
|
-
import {
|
|
3
|
+
import { allDevTools } from './tools/index.js';
|
|
4
4
|
import { logger } from './utils/logger.js';
|
|
5
|
+
import { checkToolPrerequisites } from './services/tool-guard.js';
|
|
6
|
+
import { recordToolSuccess } from './services/session-state.js';
|
|
5
7
|
/**
|
|
6
|
-
* Create the
|
|
8
|
+
* Create the Tool-First Ratio Dev MCP Server.
|
|
7
9
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* Exposes all tools individually (not a single agent_chat).
|
|
11
|
+
* Each tool call passes through the prerequisite guard.
|
|
12
|
+
* The LLM decides what to call based on user intent and get_status output.
|
|
11
13
|
*
|
|
12
|
-
*
|
|
13
|
-
* -
|
|
14
|
-
* -
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* Guard enforcement:
|
|
15
|
+
* - If prerequisites are met → tool executes normally
|
|
16
|
+
* - If prerequisites are NOT met → returns structured error with:
|
|
17
|
+
* - What's missing
|
|
18
|
+
* - The full chain of tools needed to unblock
|
|
19
|
+
* - A hint for the LLM to self-correct
|
|
20
|
+
*
|
|
21
|
+
* Session recording:
|
|
22
|
+
* - On success, tool results are parsed to extract context (appId, scopes, etc.)
|
|
23
|
+
* - This context drives future guard checks
|
|
17
24
|
*/
|
|
18
25
|
export function createOrchestratedServer() {
|
|
19
26
|
const server = new McpServer({
|
|
20
27
|
name: `${DEV_SERVER_NAME}-orchestrated`,
|
|
21
28
|
version: DEV_SERVER_VERSION,
|
|
22
29
|
});
|
|
23
|
-
// Register
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
30
|
+
// Register all tools with guard middleware
|
|
31
|
+
for (const tool of allDevTools) {
|
|
32
|
+
const shape = tool.inputSchema.shape;
|
|
33
|
+
server.tool(tool.name, tool.description, shape, async (args) => {
|
|
34
|
+
logger.toolCall(tool.name, args);
|
|
35
|
+
const startTime = Date.now();
|
|
36
|
+
// ── Guard: check prerequisites before executing ──────────────
|
|
37
|
+
const guard = checkToolPrerequisites(tool.name);
|
|
38
|
+
if (!guard.allowed) {
|
|
39
|
+
const duration = Date.now() - startTime;
|
|
40
|
+
logger.info(`BLOCKED ${tool.name} (${duration}ms): ${guard.message}`);
|
|
41
|
+
return {
|
|
42
|
+
content: [
|
|
43
|
+
{
|
|
44
|
+
type: 'text',
|
|
45
|
+
text: JSON.stringify({
|
|
46
|
+
error: true,
|
|
47
|
+
blocked: true,
|
|
48
|
+
tool: tool.name,
|
|
49
|
+
message: guard.message,
|
|
50
|
+
required_tools: guard.requiredTools,
|
|
51
|
+
chain: guard.chain,
|
|
52
|
+
hint: guard.hint || `Call ${guard.requiredTools?.join(' → ')} first, then retry ${tool.name}.`,
|
|
53
|
+
doc_hint: 'If you are unsure about any platform detail, call lookup_docs or get_status before proceeding.',
|
|
54
|
+
}, null, 2),
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
isError: true,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// ── Execute tool ────────────────────────────────────────────
|
|
61
|
+
try {
|
|
62
|
+
const result = await tool.handler(args);
|
|
63
|
+
const duration = Date.now() - startTime;
|
|
64
|
+
logger.toolResult(tool.name, duration, result);
|
|
65
|
+
// Record success in session state
|
|
66
|
+
recordToolSuccess(tool.name, result);
|
|
67
|
+
return {
|
|
68
|
+
content: [
|
|
69
|
+
{
|
|
70
|
+
type: 'text',
|
|
71
|
+
text: JSON.stringify(result, null, 2),
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
const duration = Date.now() - startTime;
|
|
78
|
+
logger.toolError(tool.name, duration, error);
|
|
79
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
80
|
+
return {
|
|
81
|
+
content: [
|
|
82
|
+
{
|
|
83
|
+
type: 'text',
|
|
84
|
+
text: JSON.stringify({
|
|
85
|
+
error: true,
|
|
86
|
+
message,
|
|
87
|
+
tool: tool.name,
|
|
88
|
+
doc_hint: 'If this error is about an API detail, call lookup_docs to verify the correct usage.',
|
|
89
|
+
}, null, 2),
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
isError: true,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
logger.debug(`Registered tool: ${tool.name}`);
|
|
97
|
+
}
|
|
98
|
+
logger.info(`${DEV_SERVER_NAME}-orchestrated initialized with ${allDevTools.length} tools (tool-first architecture)`);
|
|
61
99
|
return server;
|
|
62
100
|
}
|
|
63
101
|
//# sourceMappingURL=orchestrated-server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrated-server.js","sourceRoot":"","sources":["../src/orchestrated-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"orchestrated-server.js","sourceRoot":"","sources":["../src/orchestrated-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* In-memory session state tracker.
|
|
2
|
+
* In-memory session state tracker (per-app).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* prerequisites are met before allowing it to execute.
|
|
4
|
+
* Auth state is global (one developer per stdio session).
|
|
5
|
+
* App state is scoped per app ID — supports working on multiple apps.
|
|
7
6
|
*
|
|
8
|
-
* Single-user (stdio MCP), so
|
|
7
|
+
* Single-user (stdio MCP), so module-level state is fine.
|
|
9
8
|
* For multi-user (Streamable HTTP), this would move to Redis.
|
|
10
9
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
/** Per-app state: tracks tool completion and collected context for one app */
|
|
11
|
+
export interface AppState {
|
|
13
12
|
completedTools: Set<string>;
|
|
14
|
-
/** Key data collected during the flow */
|
|
15
13
|
context: {
|
|
16
|
-
authMode?: 'login' | 'signup';
|
|
17
|
-
signupEmail?: string;
|
|
18
|
-
developerId?: string;
|
|
19
|
-
developerToken?: string;
|
|
20
|
-
appId?: string;
|
|
21
14
|
appName?: string;
|
|
22
15
|
clientId?: string;
|
|
23
16
|
clientSecret?: string;
|
|
24
17
|
confirmedScopes?: string[];
|
|
25
18
|
scopesConfirmed?: boolean;
|
|
26
19
|
webhooksConfigured?: boolean;
|
|
20
|
+
webhookIds?: string[];
|
|
27
21
|
buildUploaded?: boolean;
|
|
28
22
|
submittedForReview?: boolean;
|
|
29
23
|
appApproved?: boolean;
|
|
@@ -37,17 +31,43 @@ export interface SessionState {
|
|
|
37
31
|
zipPath?: string;
|
|
38
32
|
latestVersionId?: string;
|
|
39
33
|
};
|
|
34
|
+
}
|
|
35
|
+
/** Global session state: auth + per-app state */
|
|
36
|
+
export interface SessionState {
|
|
37
|
+
/** Global: tools completed at session level (auth tools) */
|
|
38
|
+
completedTools: Set<string>;
|
|
39
|
+
/** Global context (auth + active app's context flattened for backward compat) */
|
|
40
|
+
context: {
|
|
41
|
+
authMode?: 'login' | 'signup';
|
|
42
|
+
signupEmail?: string;
|
|
43
|
+
developerId?: string;
|
|
44
|
+
developerToken?: string;
|
|
45
|
+
/** Currently active app ID (for tools that don't pass app_id explicitly) */
|
|
46
|
+
activeAppId?: string;
|
|
47
|
+
/** Active app's ID (backward compat — same as activeAppId) */
|
|
48
|
+
appId?: string;
|
|
49
|
+
} & AppState['context'];
|
|
50
|
+
/** Per-app state, keyed by app ID */
|
|
51
|
+
apps: Record<string, AppState>;
|
|
40
52
|
/** Timestamp of last tool call */
|
|
41
53
|
lastActivity: number;
|
|
42
54
|
}
|
|
43
|
-
/** Get current session state (read-only
|
|
44
|
-
export declare function getSession():
|
|
55
|
+
/** Get current session state (read-only reference) */
|
|
56
|
+
export declare function getSession(): SessionState;
|
|
57
|
+
/** Get state for a specific app */
|
|
58
|
+
export declare function getAppState(appId: string): AppState | undefined;
|
|
59
|
+
/** Get the currently active app ID */
|
|
60
|
+
export declare function getActiveAppId(): string | undefined;
|
|
61
|
+
/** Set the active app ID */
|
|
62
|
+
export declare function setActiveAppId(appId: string): void;
|
|
45
63
|
/** Record that a tool completed successfully and extract relevant context */
|
|
46
64
|
export declare function recordToolSuccess(toolName: string, result: unknown): void;
|
|
47
65
|
/** Reset session (for testing or starting a new flow) */
|
|
48
66
|
export declare function resetSession(): void;
|
|
49
|
-
/** Check if a specific tool has been completed */
|
|
67
|
+
/** Check if a specific tool has been completed (global or active app) */
|
|
50
68
|
export declare function hasCompleted(toolName: string): boolean;
|
|
51
69
|
/** Check if ANY of the given tools has been completed */
|
|
52
70
|
export declare function hasCompletedAny(toolNames: string[]): boolean;
|
|
71
|
+
/** Get all completed tools (global + active app) */
|
|
72
|
+
export declare function getAllCompletedTools(): string[];
|
|
53
73
|
//# sourceMappingURL=session-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../../src/services/session-state.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../../src/services/session-state.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAIH,8EAA8E;AAC9E,MAAM,WAAW,QAAQ;IACvB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED,iDAAiD;AACjD,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAE5B,iFAAiF;IACjF,OAAO,EAAE;QACP,QAAQ,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;QAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,4EAA4E;QAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,8DAA8D;QAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAExB,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAE/B,kCAAkC;IAClC,YAAY,EAAE,MAAM,CAAC;CACtB;AA4BD,sDAAsD;AACtD,wBAAgB,UAAU,IAAI,YAAY,CAEzC;AAED,mCAAmC;AACnC,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAE/D;AAED,sCAAsC;AACtC,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CAEnD;AAED,4BAA4B;AAC5B,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAuNzE;AA2BD,yDAAyD;AACzD,wBAAgB,YAAY,IAAI,IAAI,CAGnC;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAOtD;AAED,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAE5D;AAED,oDAAoD;AACpD,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAS/C"}
|