@soldy_ai/mcp 0.1.6

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.
Files changed (47) hide show
  1. package/README.md +42 -0
  2. package/dist/client.d.ts +103 -0
  3. package/dist/client.js +165 -0
  4. package/dist/client.js.map +1 -0
  5. package/dist/errors.d.ts +5 -0
  6. package/dist/errors.js +22 -0
  7. package/dist/errors.js.map +1 -0
  8. package/dist/files.d.ts +6 -0
  9. package/dist/files.js +49 -0
  10. package/dist/files.js.map +1 -0
  11. package/dist/index.d.ts +2 -0
  12. package/dist/index.js +18 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/resources/brands.d.ts +3 -0
  15. package/dist/resources/brands.js +170 -0
  16. package/dist/resources/brands.js.map +1 -0
  17. package/dist/resources/materials.d.ts +3 -0
  18. package/dist/resources/materials.js +134 -0
  19. package/dist/resources/materials.js.map +1 -0
  20. package/dist/resources/messages.d.ts +3 -0
  21. package/dist/resources/messages.js +135 -0
  22. package/dist/resources/messages.js.map +1 -0
  23. package/dist/resources/projects.d.ts +3 -0
  24. package/dist/resources/projects.js +78 -0
  25. package/dist/resources/projects.js.map +1 -0
  26. package/dist/server.d.ts +6 -0
  27. package/dist/server.js +171 -0
  28. package/dist/server.js.map +1 -0
  29. package/dist/subscriptions.d.ts +45 -0
  30. package/dist/subscriptions.js +275 -0
  31. package/dist/subscriptions.js.map +1 -0
  32. package/dist/tools/brand.d.ts +3 -0
  33. package/dist/tools/brand.js +141 -0
  34. package/dist/tools/brand.js.map +1 -0
  35. package/dist/tools/material.d.ts +2 -0
  36. package/dist/tools/material.js +23 -0
  37. package/dist/tools/material.js.map +1 -0
  38. package/dist/tools/message.d.ts +3 -0
  39. package/dist/tools/message.js +241 -0
  40. package/dist/tools/message.js.map +1 -0
  41. package/dist/tools/project.d.ts +3 -0
  42. package/dist/tools/project.js +240 -0
  43. package/dist/tools/project.js.map +1 -0
  44. package/dist/tools/subscribe.d.ts +12 -0
  45. package/dist/tools/subscribe.js +74 -0
  46. package/dist/tools/subscribe.js.map +1 -0
  47. package/package.json +37 -0
@@ -0,0 +1,134 @@
1
+ import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export function registerMaterialResources(server, client) {
3
+ server.resource("project-materials", new ResourceTemplate("soldy://project/{project_id}/materials", {
4
+ list: async () => {
5
+ try {
6
+ const projects = await client.listProjects();
7
+ return {
8
+ resources: projects.map((p) => ({
9
+ uri: `soldy://project/${p.id}/materials`,
10
+ name: `${p.name} — Materials`,
11
+ description: `Generated assets for ${p.name}`,
12
+ mimeType: "application/json",
13
+ })),
14
+ };
15
+ }
16
+ catch (err) {
17
+ console.error("[resource:project-materials] list failed:", err);
18
+ return { resources: [] };
19
+ }
20
+ },
21
+ complete: {
22
+ project_id: async (value) => {
23
+ try {
24
+ const projects = await client.listProjects();
25
+ return projects
26
+ .filter((p) => p.id.startsWith(value))
27
+ .map((p) => p.id);
28
+ }
29
+ catch {
30
+ return [];
31
+ }
32
+ },
33
+ },
34
+ }), {
35
+ title: "Project Materials",
36
+ description: "All generated assets for a project",
37
+ mimeType: "application/json",
38
+ }, async (uri, { project_id }) => {
39
+ const id = Array.isArray(project_id) ? project_id[0] : project_id;
40
+ try {
41
+ const materials = await client.getMaterials(id);
42
+ return {
43
+ contents: [
44
+ {
45
+ uri: uri.href,
46
+ mimeType: "application/json",
47
+ text: JSON.stringify({ count: materials.length, materials }, null, 2),
48
+ },
49
+ ],
50
+ };
51
+ }
52
+ catch (err) {
53
+ return {
54
+ contents: [
55
+ {
56
+ uri: uri.href,
57
+ mimeType: "application/json",
58
+ text: JSON.stringify({
59
+ error: err instanceof Error ? err.message : "Failed to fetch",
60
+ }),
61
+ },
62
+ ],
63
+ };
64
+ }
65
+ });
66
+ server.resource("run-materials", new ResourceTemplate("soldy://project/{project_id}/runs/{run_id}/materials", {
67
+ list: undefined,
68
+ complete: {
69
+ project_id: async (value) => {
70
+ try {
71
+ const projects = await client.listProjects();
72
+ return projects
73
+ .filter((p) => p.id.startsWith(value))
74
+ .map((p) => p.id);
75
+ }
76
+ catch {
77
+ return [];
78
+ }
79
+ },
80
+ run_id: async (value, context) => {
81
+ try {
82
+ const projectId = context?.arguments?.project_id;
83
+ if (!projectId)
84
+ return [];
85
+ const groups = await client.getMaterialsGrouped(projectId);
86
+ return groups
87
+ .map((g) => g.run_id)
88
+ .filter((r) => Boolean(r) && r.startsWith(value));
89
+ }
90
+ catch {
91
+ return [];
92
+ }
93
+ },
94
+ },
95
+ }), {
96
+ title: "Run Materials",
97
+ description: "Generated assets for a specific agent run. Use project-level materials to discover run_ids first.",
98
+ mimeType: "application/json",
99
+ }, async (uri, { project_id, run_id }) => {
100
+ const pid = Array.isArray(project_id) ? project_id[0] : project_id;
101
+ const rid = Array.isArray(run_id) ? run_id[0] : run_id;
102
+ try {
103
+ const groups = await client.getMaterialsGrouped(pid);
104
+ const match = groups.find((g) => g.run_id === rid);
105
+ return {
106
+ contents: [
107
+ {
108
+ uri: uri.href,
109
+ mimeType: "application/json",
110
+ text: JSON.stringify({
111
+ run_id: rid,
112
+ count: match?.materials.length ?? 0,
113
+ materials: match?.materials ?? [],
114
+ }, null, 2),
115
+ },
116
+ ],
117
+ };
118
+ }
119
+ catch (err) {
120
+ return {
121
+ contents: [
122
+ {
123
+ uri: uri.href,
124
+ mimeType: "application/json",
125
+ text: JSON.stringify({
126
+ error: err instanceof Error ? err.message : "Failed to fetch",
127
+ }),
128
+ },
129
+ ],
130
+ };
131
+ }
132
+ });
133
+ }
134
+ //# sourceMappingURL=materials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"materials.js","sourceRoot":"","sources":["../../src/resources/materials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { SoldyAPIClient } from "../client.js";
3
+ export declare function registerMessageResources(server: McpServer, client: SoldyAPIClient): void;
@@ -0,0 +1,135 @@
1
+ import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export function registerMessageResources(server, client) {
3
+ server.resource("project-messages", new ResourceTemplate("soldy://project/{project_id}/messages", {
4
+ list: async () => {
5
+ try {
6
+ const projects = await client.listProjects();
7
+ return {
8
+ resources: projects.map((p) => ({
9
+ uri: `soldy://project/${p.id}/messages`,
10
+ name: `${p.name} — Messages`,
11
+ description: `Conversation history for ${p.name}`,
12
+ mimeType: "application/json",
13
+ })),
14
+ };
15
+ }
16
+ catch (err) {
17
+ console.error("[resource:project-messages] list failed:", err);
18
+ return { resources: [] };
19
+ }
20
+ },
21
+ complete: {
22
+ project_id: async (value) => {
23
+ try {
24
+ const projects = await client.listProjects();
25
+ return projects
26
+ .filter((p) => p.id.startsWith(value))
27
+ .map((p) => p.id);
28
+ }
29
+ catch {
30
+ return [];
31
+ }
32
+ },
33
+ },
34
+ }), {
35
+ title: "Project Messages",
36
+ description: "Conversation history for a project",
37
+ mimeType: "application/json",
38
+ }, async (uri, { project_id }) => {
39
+ const id = Array.isArray(project_id) ? project_id[0] : project_id;
40
+ try {
41
+ const { messages, total } = await client.listMessages(id);
42
+ return {
43
+ contents: [
44
+ {
45
+ uri: uri.href,
46
+ mimeType: "application/json",
47
+ text: JSON.stringify({ total, messages }, null, 2),
48
+ },
49
+ ],
50
+ };
51
+ }
52
+ catch (err) {
53
+ return {
54
+ contents: [
55
+ {
56
+ uri: uri.href,
57
+ mimeType: "application/json",
58
+ text: JSON.stringify({
59
+ error: err instanceof Error ? err.message : "Failed to fetch",
60
+ }),
61
+ },
62
+ ],
63
+ };
64
+ }
65
+ });
66
+ server.resource("run-messages", new ResourceTemplate("soldy://project/{project_id}/runs/{run_id}/messages", {
67
+ list: undefined,
68
+ complete: {
69
+ project_id: async (value) => {
70
+ try {
71
+ const projects = await client.listProjects();
72
+ return projects
73
+ .filter((p) => p.id.startsWith(value))
74
+ .map((p) => p.id);
75
+ }
76
+ catch {
77
+ return [];
78
+ }
79
+ },
80
+ run_id: async (value, context) => {
81
+ try {
82
+ const projectId = context?.arguments?.project_id;
83
+ if (!projectId)
84
+ return [];
85
+ const { messages } = await client.listMessages(projectId, 1, 100);
86
+ const runIds = [
87
+ ...new Set(messages.map((m) => m.run_id).filter(Boolean)),
88
+ ];
89
+ return runIds.filter((r) => r.startsWith(value));
90
+ }
91
+ catch {
92
+ return [];
93
+ }
94
+ },
95
+ },
96
+ }), {
97
+ title: "Run Messages",
98
+ description: "Messages for a specific agent run. Use project-level messages to discover run_ids first.",
99
+ mimeType: "application/json",
100
+ }, async (uri, { project_id, run_id }) => {
101
+ const pid = Array.isArray(project_id) ? project_id[0] : project_id;
102
+ const rid = Array.isArray(run_id) ? run_id[0] : run_id;
103
+ try {
104
+ const { messages } = await client.listMessages(pid, 1, 200);
105
+ const runMessages = messages.filter((m) => m.run_id === rid);
106
+ return {
107
+ contents: [
108
+ {
109
+ uri: uri.href,
110
+ mimeType: "application/json",
111
+ text: JSON.stringify({
112
+ run_id: rid,
113
+ count: runMessages.length,
114
+ messages: runMessages,
115
+ }, null, 2),
116
+ },
117
+ ],
118
+ };
119
+ }
120
+ catch (err) {
121
+ return {
122
+ contents: [
123
+ {
124
+ uri: uri.href,
125
+ mimeType: "application/json",
126
+ text: JSON.stringify({
127
+ error: err instanceof Error ? err.message : "Failed to fetch",
128
+ }),
129
+ },
130
+ ],
131
+ };
132
+ }
133
+ });
134
+ }
135
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/resources/messages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { SoldyAPIClient } from "../client.js";
3
+ export declare function registerProjectResources(server: McpServer, client: SoldyAPIClient): void;
@@ -0,0 +1,78 @@
1
+ import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export function registerProjectResources(server, client) {
3
+ server.resource("project-status", new ResourceTemplate("soldy://project/{project_id}/status", {
4
+ list: async () => {
5
+ try {
6
+ const projects = await client.listProjects();
7
+ return {
8
+ resources: projects.map((p) => ({
9
+ uri: `soldy://project/${p.id}/status`,
10
+ name: `${p.name} — Status`,
11
+ description: `Status: ${p.status} | Ratio: ${p.ratio}`,
12
+ mimeType: "application/json",
13
+ })),
14
+ };
15
+ }
16
+ catch (err) {
17
+ console.error("[resource:project-status] list failed:", err);
18
+ return { resources: [] };
19
+ }
20
+ },
21
+ complete: {
22
+ project_id: async (value) => {
23
+ try {
24
+ const projects = await client.listProjects();
25
+ return projects
26
+ .filter((p) => p.id.startsWith(value))
27
+ .map((p) => p.id);
28
+ }
29
+ catch {
30
+ return [];
31
+ }
32
+ },
33
+ },
34
+ }), {
35
+ title: "Project Status",
36
+ description: "Current status of a project",
37
+ mimeType: "application/json",
38
+ }, async (uri, { project_id }) => {
39
+ const id = Array.isArray(project_id) ? project_id[0] : project_id;
40
+ try {
41
+ const project = await client.getProject(id);
42
+ if (!project) {
43
+ return {
44
+ contents: [
45
+ {
46
+ uri: uri.href,
47
+ mimeType: "application/json",
48
+ text: JSON.stringify({ error: "Project not found" }),
49
+ },
50
+ ],
51
+ };
52
+ }
53
+ return {
54
+ contents: [
55
+ {
56
+ uri: uri.href,
57
+ mimeType: "application/json",
58
+ text: JSON.stringify(project, null, 2),
59
+ },
60
+ ],
61
+ };
62
+ }
63
+ catch (err) {
64
+ return {
65
+ contents: [
66
+ {
67
+ uri: uri.href,
68
+ mimeType: "application/json",
69
+ text: JSON.stringify({
70
+ error: err instanceof Error ? err.message : "Failed to fetch",
71
+ }),
72
+ },
73
+ ],
74
+ };
75
+ }
76
+ });
77
+ }
78
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/resources/projects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { SubscriptionBridge } from "./subscriptions.js";
3
+ export declare function createServer(apiUrl: string, apiKey: string): {
4
+ server: McpServer;
5
+ bridge: SubscriptionBridge;
6
+ };
package/dist/server.js ADDED
@@ -0,0 +1,171 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { SubscribeRequestSchema, UnsubscribeRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
3
+ import { SoldyAPIClient } from "./client.js";
4
+ import { registerBrandResources } from "./resources/brands.js";
5
+ import { registerMaterialResources } from "./resources/materials.js";
6
+ import { registerMessageResources } from "./resources/messages.js";
7
+ import { registerProjectResources } from "./resources/projects.js";
8
+ import { extractBrandTaskId, extractProjectId, SubscriptionBridge, } from "./subscriptions.js";
9
+ import { registerBrandTools } from "./tools/brand.js";
10
+ import { registerMaterialTools } from "./tools/material.js";
11
+ import { registerMessageTools } from "./tools/message.js";
12
+ import { registerProjectTools } from "./tools/project.js";
13
+ import { registerSubscribeTools } from "./tools/subscribe.js";
14
+ export function createServer(apiUrl, apiKey) {
15
+ const server = new McpServer({ name: "Soldy AI", version: "0.1.0" }, {
16
+ capabilities: { tools: {}, prompts: {}, resources: { subscribe: true } },
17
+ instructions: SERVER_INSTRUCTIONS,
18
+ });
19
+ const client = new SoldyAPIClient(apiUrl, apiKey);
20
+ const bridge = new SubscriptionBridge(client, apiUrl, apiKey);
21
+ // Tools
22
+ registerBrandTools(server, client);
23
+ registerProjectTools(server, client);
24
+ registerMessageTools(server, client);
25
+ registerMaterialTools(server, apiUrl);
26
+ registerSubscribeTools(server, bridge);
27
+ // Resources
28
+ registerBrandResources(server, client);
29
+ registerProjectResources(server, client);
30
+ registerMessageResources(server, client);
31
+ registerMaterialResources(server, client);
32
+ // Standard MCP resources/subscribe & resources/unsubscribe handlers.
33
+ // McpServer does not register these automatically — only list/read are
34
+ // wired up by the high-level API. We register on the low-level Server
35
+ // instance so clients can use the standard subscription protocol.
36
+ server.server.setRequestHandler(SubscribeRequestSchema, async (request) => {
37
+ const uri = request.params.uri;
38
+ const projectId = extractProjectId(uri);
39
+ if (projectId) {
40
+ await bridge.subscribeProject(projectId);
41
+ return {};
42
+ }
43
+ const taskId = extractBrandTaskId(uri);
44
+ if (taskId) {
45
+ bridge.subscribeBrandTask(taskId);
46
+ return {};
47
+ }
48
+ // For other resources (soldy://brands, etc.), acknowledge silently
49
+ return {};
50
+ });
51
+ server.server.setRequestHandler(UnsubscribeRequestSchema, async (request) => {
52
+ const uri = request.params.uri;
53
+ const projectId = extractProjectId(uri);
54
+ if (projectId) {
55
+ bridge.unsubscribeProject(projectId);
56
+ return {};
57
+ }
58
+ const taskId = extractBrandTaskId(uri);
59
+ if (taskId) {
60
+ bridge.unsubscribeBrandTask(taskId);
61
+ return {};
62
+ }
63
+ return {};
64
+ });
65
+ // Workflow prompt
66
+ server.prompt("soldy_workflow", "Recommended workflow for creating video ads with Soldy", () => ({
67
+ messages: [
68
+ {
69
+ role: "user",
70
+ content: {
71
+ type: "text",
72
+ text: WORKFLOW_PROMPT,
73
+ },
74
+ },
75
+ ],
76
+ }));
77
+ return { server, bridge };
78
+ }
79
+ // ---------------------------------------------------------------------------
80
+ // Server-level instructions — injected into the MCP server metadata so agents
81
+ // always see them, regardless of which tools they discover first.
82
+ // ---------------------------------------------------------------------------
83
+ const SERVER_INSTRUCTIONS = `# Soldy AI MCP Server
84
+
85
+ ## Available Resources (read & subscribe)
86
+
87
+ This server exposes MCP resources you can read and subscribe to for real-time updates.
88
+ Use resources instead of polling tools whenever possible.
89
+
90
+ ### Resource URI Scheme
91
+
92
+ | URI | Description | Subscribable |
93
+ |-----|-------------|:---:|
94
+ | \`soldy://brands\` | All brands in the workspace | ✓ |
95
+ | \`soldy://brand/{brand_id}\` | Single brand detail | ✓ |
96
+ | \`soldy://brand/task/{task_id}\` | Brand extraction task status | ✓ |
97
+ | \`soldy://project/{project_id}/status\` | Project status | ✓ |
98
+ | \`soldy://project/{project_id}/messages\` | Conversation history | ✓ |
99
+ | \`soldy://project/{project_id}/materials\` | Generated assets (videos, images, etc.) | ✓ |
100
+ | \`soldy://project/{project_id}/runs/{run_id}/messages\` | Messages for a specific agent run | ✓ |
101
+ | \`soldy://project/{project_id}/runs/{run_id}/materials\` | Materials for a specific agent run | ✓ |
102
+
103
+ ### Subscription Pattern (preferred over polling)
104
+
105
+ Instead of calling get_project_status in a loop, subscribe for real-time push notifications:
106
+
107
+ 1. Call \`watch_project(project_id)\` or \`watch_brand_task(task_id)\`
108
+ 2. You will receive resource update notifications when data changes
109
+ 3. Read the notified resource URI to get updated data
110
+
111
+ ### Recommended Workflow
112
+
113
+ - **Brand extraction**: \`extract_brand\` → \`watch_brand_task\` → wait for notification → read \`soldy://brand/task/{task_id}\`
114
+ - **Video generation**: \`send_message\` → \`watch_project\` → wait for notifications → read \`soldy://project/{id}/status\` or \`soldy://project/{id}/materials\`
115
+
116
+ ### Polling Fallback
117
+
118
+ If subscription is not available in your client, you can still use:
119
+ - \`get_project_status\` — check project status
120
+ - \`get_brand_task_result\` — check brand task status
121
+ - \`list_messages\` — get conversation history
122
+ - \`get_project_materials\` — get generated assets
123
+ `;
124
+ const WORKFLOW_PROMPT = `# Soldy Video Ad Workflow
125
+
126
+ ## Quick Start (3 steps)
127
+ 1. create_project → get project_id
128
+ 2. send_message with your prompt + material_urls (product images/videos)
129
+ 3. watch_project to subscribe → read resources when notified
130
+
131
+ ## Full Workflow with Brand
132
+
133
+ ### Step 1: Brand Setup (recommended for best results)
134
+ If the user provides a product URL or brand name:
135
+ - Use extract_brand with the product/brand URL to auto-extract brand identity
136
+ - Use watch_brand_task to subscribe for completion (preferred) or poll get_brand_task_result
137
+ - This gives the agent brand context (colors, tone, positioning)
138
+
139
+ If user already has brands: list_brands to find the right brand_id
140
+
141
+ ### Step 2: Create Project
142
+ - create_project with a descriptive name
143
+
144
+ ### Step 3: Send Message with Materials
145
+ - send_message with:
146
+ - content: describe what to generate
147
+ - ratio (required): "9:16" (TikTok/Reels/Shorts), "16:9" (YouTube), "1:1" (Instagram), "4:3", "3:4", "3:2", "2:3", "21:9" (ultra-wide)
148
+ - material_urls: product images, videos (local paths auto-uploaded)
149
+ - brand_id: the brand from step 1
150
+
151
+ ### Step 4: Monitor Progress (prefer subscription over polling)
152
+ - **Preferred**: watch_project → wait for resource update notifications
153
+ - **Fallback**: get_project_status to poll status
154
+ - If status is "pause": agent needs credits or approval → use continue_project
155
+ - If status is "error": check the error, retry with send_message
156
+ - If status is "completed": proceed to step 5
157
+
158
+ ### Step 5: Get Results
159
+ - Read resource: soldy://project/{id}/materials
160
+ - Or use tool: get_project_materials
161
+
162
+ ### Step 6: Iterate
163
+ - send_message again to refine, change style, adjust duration, etc.
164
+
165
+ ## Tips
166
+ - Always pass brand_id in send_message when a brand exists
167
+ - ratio is required in send_message — choose based on target platform
168
+ - Product URLs in text are NOT automatically extracted — use extract_brand explicitly
169
+ - Local file paths (./image.jpg, /path/to/video.mp4) are uploaded automatically
170
+ - Use watch_project / watch_brand_task for real-time updates instead of polling`;
171
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import type { SoldyAPIClient } from "./client.js";
3
+ /**
4
+ * Bridges WebSocket project subscriptions to MCP resource update notifications.
5
+ *
6
+ * When an MCP client subscribes to a resource URI (e.g. `soldy://project/{id}/status`),
7
+ * this bridge connects to the API WebSocket, subscribes to the project, and forwards
8
+ * relevant events as `sendResourceUpdated` notifications.
9
+ */
10
+ export declare class SubscriptionBridge {
11
+ private client;
12
+ private apiKey;
13
+ private ws;
14
+ private subscribedProjects;
15
+ private connecting;
16
+ private reconnectTimer;
17
+ private reconnectDelay;
18
+ private maxReconnectDelay;
19
+ private server;
20
+ /** Brand task polling: taskId → { interval, lastStatus } */
21
+ private brandTaskPolls;
22
+ private static readonly BRAND_TASK_POLL_MS;
23
+ constructor(client: SoldyAPIClient, _apiUrl: string, apiKey: string);
24
+ /** Attach the low-level MCP Server instance for sending notifications. */
25
+ setServer(server: Server): void;
26
+ /** Subscribe to a project's WebSocket events. Call when MCP client subscribes to a resource. */
27
+ subscribeProject(projectId: string): Promise<void>;
28
+ /** Unsubscribe from a project. Call when no more MCP subscriptions reference it. */
29
+ unsubscribeProject(projectId: string): void;
30
+ /** Subscribe to brand task status changes via polling. */
31
+ subscribeBrandTask(taskId: string): void;
32
+ /** Stop polling a brand task. */
33
+ unsubscribeBrandTask(taskId: string): void;
34
+ /** Disconnect the WebSocket and stop all polling. */
35
+ disconnect(): void;
36
+ private ensureConnected;
37
+ private connect;
38
+ private scheduleReconnect;
39
+ private sendProjectSubscribe;
40
+ private handleMessage;
41
+ }
42
+ /** Extract project_id from a soldy://project/... resource URI. */
43
+ export declare function extractProjectId(uri: string): string | null;
44
+ /** Extract task_id from a soldy://brand/task/... resource URI. */
45
+ export declare function extractBrandTaskId(uri: string): string | null;