@runapi.ai/suno-mcp 0.1.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.
@@ -0,0 +1,82 @@
1
+ {
2
+ "endpoints": {
3
+ "suno-v4/cover_audio": {
4
+ "unit_price_cents": 12
5
+ },
6
+ "suno-v4/create_mashup": {
7
+ "unit_price_cents": 12
8
+ },
9
+ "suno-v4/extend_music": {
10
+ "unit_price_cents": 12
11
+ },
12
+ "suno-v4/text_to_music": {
13
+ "unit_price_cents": 12
14
+ },
15
+ "suno-v4.5/cover_audio": {
16
+ "unit_price_cents": 12
17
+ },
18
+ "suno-v4.5/create_mashup": {
19
+ "unit_price_cents": 12
20
+ },
21
+ "suno-v4.5/extend_music": {
22
+ "unit_price_cents": 12
23
+ },
24
+ "suno-v4.5/text_to_music": {
25
+ "unit_price_cents": 12
26
+ },
27
+ "suno-v4.5-all/cover_audio": {
28
+ "unit_price_cents": 12
29
+ },
30
+ "suno-v4.5-all/create_mashup": {
31
+ "unit_price_cents": 12
32
+ },
33
+ "suno-v4.5-all/extend_music": {
34
+ "unit_price_cents": 12
35
+ },
36
+ "suno-v4.5-all/text_to_music": {
37
+ "unit_price_cents": 12
38
+ },
39
+ "suno-v4.5-plus/cover_audio": {
40
+ "unit_price_cents": 12
41
+ },
42
+ "suno-v4.5-plus/create_mashup": {
43
+ "unit_price_cents": 12
44
+ },
45
+ "suno-v4.5-plus/extend_music": {
46
+ "unit_price_cents": 12
47
+ },
48
+ "suno-v4.5-plus/text_to_music": {
49
+ "unit_price_cents": 12
50
+ },
51
+ "suno-v5/cover_audio": {
52
+ "unit_price_cents": 12
53
+ },
54
+ "suno-v5/create_mashup": {
55
+ "unit_price_cents": 12
56
+ },
57
+ "suno-v5/extend_music": {
58
+ "unit_price_cents": 12
59
+ },
60
+ "suno-v5/text_to_music": {
61
+ "unit_price_cents": 12
62
+ },
63
+ "suno-v5/text_to_sound": {
64
+ "unit_price_cents": 3
65
+ },
66
+ "suno-v5.5/cover_audio": {
67
+ "unit_price_cents": 12
68
+ },
69
+ "suno-v5.5/create_mashup": {
70
+ "unit_price_cents": 12
71
+ },
72
+ "suno-v5.5/extend_music": {
73
+ "unit_price_cents": 12
74
+ },
75
+ "suno-v5.5/text_to_music": {
76
+ "unit_price_cents": 12
77
+ },
78
+ "suno-v5.5/text_to_sound": {
79
+ "unit_price_cents": 3
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import "../src/index.js";
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import "../src/index.js";
3
+ //# sourceMappingURL=suno-mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suno-mcp.js","sourceRoot":"","sources":["../../bin/suno-mcp.ts"],"names":[],"mappings":";AACA,OAAO,iBAAiB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Contract, PricingConfig } from "@runapi.ai/mcp-core";
2
+ export declare function readContract(): Contract;
3
+ export declare function readPricing(): PricingConfig;
@@ -0,0 +1,22 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { fileURLToPath } from "node:url";
3
+ import path from "node:path";
4
+ function dataRoot() {
5
+ const current = path.dirname(fileURLToPath(import.meta.url));
6
+ const candidates = [
7
+ path.resolve(current, "..", "..", "data"),
8
+ path.resolve(current, "..", "data")
9
+ ];
10
+ const root = candidates.find((candidate) => existsSync(path.join(candidate, "contract.json")));
11
+ if (!root) {
12
+ throw new Error("Unable to locate the embedded RunAPI data directory.");
13
+ }
14
+ return root;
15
+ }
16
+ export function readContract() {
17
+ return JSON.parse(readFileSync(path.join(dataRoot(), "contract.json"), "utf8"));
18
+ }
19
+ export function readPricing() {
20
+ return JSON.parse(readFileSync(path.join(dataRoot(), "pricing.json"), "utf8"));
21
+ }
22
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sourceRoot":"","sources":["../../src/data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,SAAS,QAAQ;IACf,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC;KACpC,CAAC;IAEF,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IAC/F,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,eAAe,CAAC,EAAE,MAAM,CAAC,CAAa,CAAC;AAC9F,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAkB,CAAC;AAClG,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { createServer } from "./server.js";
4
+ const server = createServer();
5
+ await server.connect(new StdioServerTransport());
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;AAC9B,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare const META: {
2
+ readonly name: "@runapi.ai/suno-mcp";
3
+ readonly version: "0.1.0";
4
+ readonly lineSlug: "suno";
5
+ };
@@ -0,0 +1,6 @@
1
+ export const META = {
2
+ name: "@runapi.ai/suno-mcp",
3
+ version: "0.1.0",
4
+ lineSlug: "suno"
5
+ };
6
+ //# sourceMappingURL=meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/meta.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,IAAI,EAAE,qBAAqB;IAC3B,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,MAAM;CACR,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function createServer(): McpServer;
@@ -0,0 +1,147 @@
1
+ import { z } from "zod";
2
+ import { createModelServer, findModelForAction, findModels, friendlyError, jsonText, priceForModel, RunApiClient, taskStatus } from "@runapi.ai/mcp-core";
3
+ import { readContract, readPricing } from "./data.js";
4
+ import { META } from "./meta.js";
5
+ const RESERVED_FIELDS = new Set(["model", "rules"]);
6
+ function lineService(contract) {
7
+ return Object.keys(contract.actions)[0]?.split("/")[0] ?? META.lineSlug;
8
+ }
9
+ function lineEndpoints(contract) {
10
+ const seen = new Set();
11
+ for (const action of Object.values(contract.actions)) {
12
+ seen.add(action.endpoint);
13
+ }
14
+ return [...seen];
15
+ }
16
+ function lineModels(contract) {
17
+ const seen = new Set();
18
+ for (const action of Object.values(contract.actions)) {
19
+ for (const model of action.models) {
20
+ seen.add(model);
21
+ }
22
+ }
23
+ return [...seen];
24
+ }
25
+ function fieldsForAction(action) {
26
+ const fields = {};
27
+ for (const model of action.models) {
28
+ const roster = action.fields_by_model[model] ?? {};
29
+ for (const [name, field] of Object.entries(roster)) {
30
+ if (RESERVED_FIELDS.has(name)) {
31
+ continue;
32
+ }
33
+ if (!(name in fields)) {
34
+ fields[name] = field;
35
+ }
36
+ }
37
+ }
38
+ return fields;
39
+ }
40
+ function rulesForAction(action) {
41
+ for (const model of action.models) {
42
+ const roster = action.fields_by_model[model] ?? {};
43
+ const rules = roster.rules;
44
+ if (Array.isArray(rules) && rules.length > 0) {
45
+ return rules;
46
+ }
47
+ }
48
+ return [];
49
+ }
50
+ function buildTools(contract) {
51
+ const tools = [];
52
+ const inputRules = {};
53
+ for (const [key, action] of Object.entries(contract.actions)) {
54
+ const service = key.split("/")[0];
55
+ const endpoint = action.endpoint;
56
+ tools.push({
57
+ name: endpoint,
58
+ description: `Create a ${action.model} task on RunAPI (${endpoint.replace(/_/g, " ")}). Returns a task id, status, and output URLs.`,
59
+ service,
60
+ action: endpoint,
61
+ models: action.models,
62
+ inputSchema: fieldsForAction(action)
63
+ });
64
+ inputRules[endpoint] = rulesForAction(action);
65
+ }
66
+ return { tools, inputRules };
67
+ }
68
+ function registerLineTools(server, contract, pricing, client) {
69
+ const service = lineService(contract);
70
+ const endpoints = lineEndpoints(contract);
71
+ const models = lineModels(contract);
72
+ const endpointEnum = endpoints.length > 0 ? z.enum(endpoints) : z.string();
73
+ const modelEnum = models.length > 0 ? z.enum(models) : z.string();
74
+ // With one endpoint, action defaults safely. With several, a wrong default
75
+ // would query the wrong task route, so the caller must name the endpoint.
76
+ const getTaskAction = endpoints.length > 1
77
+ ? endpointEnum.describe("Endpoint the task was created on.")
78
+ : endpointEnum.optional().describe("Endpoint the task was created on. Defaults to the line's only endpoint.");
79
+ server.tool("get_task", `Fetch the current status and latest result payload for a ${META.lineSlug} task.`, {
80
+ task_id: z.string().describe("Task id returned when the task was created."),
81
+ action: getTaskAction
82
+ }, async ({ task_id, action }) => {
83
+ try {
84
+ const task = await client.getTask(service, task_id, action ?? endpoints[0]);
85
+ return jsonText({ task_id, status: taskStatus(task), task });
86
+ }
87
+ catch (error) {
88
+ return jsonText({ error: friendlyError(error) });
89
+ }
90
+ });
91
+ server.tool("check_pricing", `Look up RunAPI pricing for the ${META.lineSlug} model line.`, {
92
+ model: modelEnum.optional().describe("Model slug. Defaults to the line's primary model."),
93
+ action: endpointEnum.optional().describe("Endpoint name. Defaults to the endpoint that offers the model.")
94
+ }, async ({ model, action }) => {
95
+ const noMatch = { supported: false, message: "No matching model/endpoint in this model line." };
96
+ // Explicit endpoint: price exactly that model on that endpoint.
97
+ if (action) {
98
+ const info = findModelForAction(service, action, model, contract);
99
+ return info
100
+ ? jsonText({ supported: true, model: info.model, service: info.service, action: info.action, price: priceForModel(info, pricing) })
101
+ : jsonText(noMatch);
102
+ }
103
+ // No endpoint and no model: price the line's primary model/endpoint.
104
+ if (!model) {
105
+ const info = findModelForAction(service, endpoints[0], undefined, contract);
106
+ return info
107
+ ? jsonText({ supported: true, model: info.model, service: info.service, action: info.action, price: priceForModel(info, pricing) })
108
+ : jsonText(noMatch);
109
+ }
110
+ // No endpoint named: a model may be offered on several endpoints at
111
+ // different prices, so report every endpoint that offers it rather than
112
+ // silently pricing only the first one found.
113
+ const matches = findModels(model, contract);
114
+ if (matches.length === 0) {
115
+ return jsonText(noMatch);
116
+ }
117
+ if (matches.length === 1) {
118
+ const info = matches[0];
119
+ return jsonText({ supported: true, model: info.model, service: info.service, action: info.action, price: priceForModel(info, pricing) });
120
+ }
121
+ return jsonText({
122
+ supported: true,
123
+ model: matches[0].model,
124
+ service: matches[0].service,
125
+ endpoints: matches.map((info) => ({ action: info.action, price: priceForModel(info, pricing) }))
126
+ });
127
+ });
128
+ }
129
+ export function createServer() {
130
+ const contract = readContract();
131
+ const pricing = readPricing();
132
+ const { tools, inputRules } = buildTools(contract);
133
+ const client = new RunApiClient();
134
+ const server = createModelServer({
135
+ name: META.name,
136
+ version: META.version,
137
+ lineSlug: META.lineSlug,
138
+ contract,
139
+ pricing,
140
+ inputRules,
141
+ tools,
142
+ client
143
+ });
144
+ registerLineTools(server, contract, pricing, client);
145
+ return server;
146
+ }
147
+ //# 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,14 @@
1
+ {
2
+ "mcpServers": {
3
+ "suno": {
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "@runapi.ai/suno-mcp"
8
+ ],
9
+ "env": {
10
+ "RUNAPI_API_KEY": "${RUNAPI_API_KEY}"
11
+ }
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "mcpServers": {
3
+ "suno": {
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "@runapi.ai/suno-mcp"
8
+ ],
9
+ "env": {
10
+ "RUNAPI_API_KEY": "${RUNAPI_API_KEY}"
11
+ }
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "mcpServers": {
3
+ "suno": {
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "@runapi.ai/suno-mcp"
8
+ ],
9
+ "env": {
10
+ "RUNAPI_API_KEY": "${RUNAPI_API_KEY}"
11
+ }
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "servers": {
3
+ "suno": {
4
+ "type": "stdio",
5
+ "command": "npx",
6
+ "args": [
7
+ "-y",
8
+ "@runapi.ai/suno-mcp"
9
+ ],
10
+ "env": {
11
+ "RUNAPI_API_KEY": "${RUNAPI_API_KEY}"
12
+ }
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "mcpServers": {
3
+ "suno": {
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "@runapi.ai/suno-mcp"
8
+ ],
9
+ "env": {
10
+ "RUNAPI_API_KEY": "${RUNAPI_API_KEY}"
11
+ }
12
+ }
13
+ }
14
+ }
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@runapi.ai/suno-mcp",
3
+ "version": "0.1.0",
4
+ "description": "RunAPI MCP server for one model line: create tasks, poll status, and check pricing with one API key.",
5
+ "type": "module",
6
+ "main": "dist/src/index.js",
7
+ "bin": {
8
+ "suno-mcp": "dist/bin/suno-mcp.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "data/contract.json",
13
+ "data/pricing.json",
14
+ "examples",
15
+ "server.json",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc -p tsconfig.json",
21
+ "dev": "tsx src/index.ts",
22
+ "prepack": "npm run build",
23
+ "typecheck": "tsc --noEmit",
24
+ "test": "vitest run"
25
+ },
26
+ "keywords": [
27
+ "runapi",
28
+ "mcp",
29
+ "model-context-protocol",
30
+ "ai"
31
+ ],
32
+ "author": "RunAPI",
33
+ "license": "Apache-2.0",
34
+ "homepage": "https://runapi.ai",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/runapi-ai/suno-mcp.git"
38
+ },
39
+ "bugs": {
40
+ "url": "https://github.com/runapi-ai/suno-mcp/issues"
41
+ },
42
+ "engines": {
43
+ "node": ">=22.0.0"
44
+ },
45
+ "dependencies": {
46
+ "@modelcontextprotocol/sdk": "^1.29.0",
47
+ "@runapi.ai/mcp-core": "0.1.0",
48
+ "zod": "^3.25.76"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^24.10.1",
52
+ "tsx": "^4.20.6",
53
+ "typescript": "^5.9.3",
54
+ "vitest": "^4.0.14"
55
+ },
56
+ "publishConfig": {
57
+ "access": "public"
58
+ },
59
+ "mcpName": "io.github.runapi-builder/suno-mcp"
60
+ }
package/server.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.runapi-builder/suno-mcp",
4
+ "description": "RunAPI MCP server for Suno: create tasks, poll status, and check pricing.",
5
+ "repository": {
6
+ "url": "https://github.com/runapi-ai/suno-mcp",
7
+ "source": "github"
8
+ },
9
+ "version": "0.1.0",
10
+ "packages": [
11
+ {
12
+ "registryType": "npm",
13
+ "identifier": "@runapi.ai/suno-mcp",
14
+ "version": "0.1.0",
15
+ "transport": {
16
+ "type": "stdio"
17
+ },
18
+ "environmentVariables": [
19
+ {
20
+ "description": "RunAPI API key. Get one at https://runapi.ai",
21
+ "isRequired": true,
22
+ "format": "string",
23
+ "isSecret": true,
24
+ "name": "RUNAPI_API_KEY"
25
+ }
26
+ ]
27
+ }
28
+ ]
29
+ }