@athanlab/mcp 0.0.0-stage → 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,284 @@
1
+ export class AthanLabError extends Error {
2
+ code;
3
+ source;
4
+ status;
5
+ type;
6
+ retryable;
7
+ retryAfterSeconds;
8
+ requestId;
9
+ docUrl;
10
+ param;
11
+ details;
12
+ upgradeUrl;
13
+ outcomeUnknown;
14
+ jobId;
15
+ /** Set by a tool that knows better than the code alone what the agent should do. */
16
+ actionOverride = null;
17
+ constructor(init) {
18
+ super(init.message);
19
+ this.name = 'AthanLabError';
20
+ this.code = init.code;
21
+ this.source = init.source;
22
+ this.status = init.status ?? null;
23
+ this.type = init.type ?? null;
24
+ this.retryable = init.retryable ?? false;
25
+ this.retryAfterSeconds = init.retryAfterSeconds ?? null;
26
+ this.requestId = init.requestId ?? null;
27
+ this.docUrl = init.docUrl ?? null;
28
+ this.param = init.param ?? null;
29
+ this.details = init.details ?? null;
30
+ this.upgradeUrl = init.upgradeUrl ?? null;
31
+ this.jobId = init.jobId ?? null;
32
+ this.outcomeUnknown = init.outcomeUnknown ?? false;
33
+ }
34
+ static fromEnvelope(body, status, retryAfterSeconds, headerRequestId) {
35
+ return new AthanLabError({
36
+ code: body.code,
37
+ message: body.message,
38
+ source: 'api',
39
+ status,
40
+ type: body.type,
41
+ retryable: body.retryable === true,
42
+ retryAfterSeconds,
43
+ requestId: body.request_id ?? headerRequestId,
44
+ docUrl: body.doc_url ?? null,
45
+ param: body.param ?? null,
46
+ details: isRecord(body.details) ? body.details : null,
47
+ upgradeUrl: typeof body.upgrade_url === 'string' ? body.upgrade_url : null,
48
+ });
49
+ }
50
+ static client(code, message, extra = {}) {
51
+ return new AthanLabError({ ...extra, code, message, source: 'client', retryable: false });
52
+ }
53
+ /** What the agent should do about it — always a sentence, never empty. */
54
+ get action() {
55
+ return this.actionOverride ?? actionFor(this);
56
+ }
57
+ toJSON() {
58
+ return {
59
+ code: this.code,
60
+ message: this.message,
61
+ source: this.source,
62
+ http_status: this.status,
63
+ retryable: this.retryable,
64
+ retry_after_seconds: this.retryAfterSeconds,
65
+ request_id: this.requestId,
66
+ param: this.param,
67
+ job_id: this.jobId,
68
+ action: this.action,
69
+ doc_url: this.docUrl,
70
+ upgrade_url: this.upgradeUrl,
71
+ details: this.details,
72
+ };
73
+ }
74
+ }
75
+ export function isRecord(value) {
76
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
77
+ }
78
+ /**
79
+ * Errors that mean "stop creating jobs": nothing about the next line or the
80
+ * next text will make them succeed. A script run stops starting new lines on
81
+ * these and reports what finished.
82
+ */
83
+ export const ACCOUNT_STOP_CODES = new Set([
84
+ 'plan_required',
85
+ 'insufficient_characters',
86
+ 'key_budget_exceeded',
87
+ 'missing_api_key',
88
+ 'invalid_api_key',
89
+ 'invalid_api_key_format',
90
+ 'scope_missing',
91
+ 'developer_pending',
92
+ 'developer_rejected',
93
+ 'developer_suspended',
94
+ 'developer_not_approved',
95
+ 'account_suspended',
96
+ 'auth_blocked',
97
+ 'api_disabled',
98
+ 'api_read_only',
99
+ 'endpoint_removed',
100
+ ]);
101
+ /** Errors that belong to ONE text: fix that line, the others can go on. */
102
+ export const LINE_ERROR_CODES = new Set([
103
+ 'validation_error',
104
+ 'unspeakable_text',
105
+ 'text_too_long',
106
+ 'voice_not_found',
107
+ 'payload_too_large',
108
+ 'input_rejected',
109
+ 'max_chars_exceeded',
110
+ ]);
111
+ const DASHBOARD = 'the Developer API page of your AthanLab dashboard (https://athanlab.com/dashboard/api)';
112
+ /** Codes whose action already says what to do about the job they name. */
113
+ const JOB_AWARE_CODES = new Set([
114
+ 'timeout',
115
+ 'gateway_unavailable',
116
+ 'network_error',
117
+ 'job_not_finished',
118
+ 'job_failed',
119
+ 'audio_expired',
120
+ 'not_found',
121
+ 'cancelled',
122
+ 'idempotency_conflict',
123
+ ]);
124
+ /** Codes whose generic action is "try again" — which, next to a paid job, reads as "speak again". */
125
+ const TRY_AGAIN_CODES = new Set(['internal_error', 'internal_client_error', 'invalid_response', 'download_failed']);
126
+ function actionFor(e) {
127
+ const base = baseActionFor(e);
128
+ if (e.jobId && e.source !== 'job' && !JOB_AWARE_CODES.has(e.code)) {
129
+ // The job succeeded and was charged; only saving its audio failed (athanlab_speak's
130
+ // download, athanlab_download_audio). The retry is the free download — never a new job.
131
+ const save = `The job (job_id ${e.jobId}) exists and was paid for; only saving its audio failed. Save it with athanlab_download_audio (job_id ${e.jobId}) — downloads are free. Do NOT call athanlab_speak again: that would create and charge a second job.`;
132
+ if (e.retryable || TRY_AGAIN_CODES.has(e.code)) {
133
+ return e.retryAfterSeconds !== null ? `Wait ${e.retryAfterSeconds} seconds. ${save}` : save;
134
+ }
135
+ return `${base} ${save}`;
136
+ }
137
+ const key = e.details?.idempotency_key;
138
+ if (typeof key === 'string' && e.retryable) {
139
+ return `${base} To retry this create safely, call the same tool with idempotency_key "${key}": if the job was already created the API returns it instead of charging again.`;
140
+ }
141
+ return base;
142
+ }
143
+ function baseActionFor(e) {
144
+ const wait = e.retryAfterSeconds !== null ? `${e.retryAfterSeconds} seconds` : 'a short while';
145
+ const detail = (key) => e.details?.[key];
146
+ switch (e.code) {
147
+ case 'plan_required':
148
+ return `Creating speech jobs needs an active Max plan (or founder access). Until then this key is read-only: athanlab_get_job, athanlab_list_jobs, athanlab_download_audio, athanlab_cancel_job and athanlab_usage keep working. Subscribe at ${e.upgradeUrl ?? 'https://athanlab.com/dashboard/profile#plans'}. Not retried.`;
149
+ case 'insufficient_characters': {
150
+ const need = detail('required');
151
+ const have = detail('spendable');
152
+ const numbers = typeof need === 'number' && typeof have === 'number' ? ` This needs ${need} characters; the account can spend ${have}.` : '';
153
+ return `Nothing was charged.${numbers} Top up Athan Tokens or wait for the monthly allowance to reset (athanlab_usage shows monthly.resets_at), or send a shorter text. Not retried.`;
154
+ }
155
+ case 'key_budget_exceeded': {
156
+ const resets = detail('resets_at');
157
+ return `This API key reached its monthly character budget; nothing was charged. Raise the key's monthly budget on ${DASHBOARD}${typeof resets === 'string' ? `, or wait until it resets at ${resets}` : ''}. Not retried.`;
158
+ }
159
+ case 'concurrency_limit':
160
+ return 'The account already has its maximum number of jobs running. This server waits and retries automatically; if it keeps happening, wait for running jobs to finish (athanlab_list_jobs with status "processing").';
161
+ case 'missing_api_key':
162
+ case 'invalid_api_key':
163
+ return 'Check ATHANLAB_API_KEY in this MCP server\'s configuration: it must be a live, unrevoked key (ak_live_ + 32 hex characters) from ' + DASHBOARD + '. Never retried — 20 failed key checks in 5 minutes block your whole network for 10 minutes.';
164
+ case 'invalid_api_key_format':
165
+ return 'Fix ATHANLAB_API_KEY in this MCP server\'s configuration (ak_live_ + exactly 32 lowercase hex characters) and restart the server. Nothing was sent to the API.';
166
+ case 'scope_missing': {
167
+ const scope = detail('required_scope');
168
+ return `This API key lacks the scope this tool needs${typeof scope === 'string' ? ` (${scope})` : ''}. Create a key with that scope on ${DASHBOARD} and update ATHANLAB_API_KEY.`;
169
+ }
170
+ case 'auth_blocked':
171
+ return `Too many failed key checks from this network: requests are blocked for ${wait}. Fix ATHANLAB_API_KEY first, then try again after the block.`;
172
+ case 'rate_limited':
173
+ return `Rate limit reached. Wait ${wait} and try again.`;
174
+ case 'developer_pending':
175
+ return 'The developer application is still under review; keys start working once it is approved.';
176
+ case 'developer_rejected':
177
+ case 'developer_not_approved':
178
+ return `This account has no approved developer application. See ${DASHBOARD}.`;
179
+ case 'developer_suspended':
180
+ case 'account_suspended':
181
+ return 'API access for this account is suspended. Contact support@athanlab.com (quote the request_id).';
182
+ case 'api_disabled':
183
+ case 'api_read_only':
184
+ return `The AthanLab API is not accepting new jobs right now (maintenance). Existing jobs, downloads and usage stay readable. Try again in ${wait}.`;
185
+ case 'capacity_unavailable':
186
+ case 'server_restarting':
187
+ case 'server_busy':
188
+ case 'service_unavailable':
189
+ return `Temporary capacity or restart; nothing was charged. Try again in ${wait}.`;
190
+ case 'gateway_unavailable':
191
+ case 'network_error':
192
+ return e.jobId
193
+ ? `The connection failed; the job may still be running. Check it with athanlab_get_job (job_id ${e.jobId}) instead of creating a new one.`
194
+ : 'The connection to the API failed. Try again shortly; a create is retried with the same Idempotency-Key, so it is never charged twice.';
195
+ case 'internal_error':
196
+ return 'Something failed on AthanLab\'s side. Try again; if it keeps failing, contact support@athanlab.com with the request_id.';
197
+ case 'validation_error':
198
+ return `Fix the request${e.param ? ` (parameter: ${e.param})` : ''} and try again.`;
199
+ case 'unspeakable_text':
200
+ return 'The text has nothing to read aloud (only emoji, punctuation or whitespace). Send Burmese words. Nothing was charged.';
201
+ case 'text_too_long':
202
+ return 'Shorten the text, add sentence punctuation (။ ! ?) so it can be split, or choose a number_mode that writes numbers out more briefly. Nothing was charged. See the athanlab-writing-guide.';
203
+ case 'voice_not_found':
204
+ return 'Call athanlab_list_voices and pass one of the ids it returns as voice_id.';
205
+ case 'idempotency_conflict': {
206
+ const job = detail('job_id');
207
+ return `This Idempotency-Key was first used for a different request${typeof job === 'string' ? ` (job_id ${job})` : ''}; nothing new was created or charged. A key only ever replays the identical request.${typeof job === 'string' ? ` If that job is the one you meant, check it with athanlab_get_job.` : ''}`;
208
+ }
209
+ case 'not_found':
210
+ return 'No such job (or voice) for this account. Check the id; athanlab_list_jobs lists your jobs.';
211
+ case 'job_not_finished':
212
+ return `The job is still processing. Check it with athanlab_get_job${e.jobId ? ` (job_id ${e.jobId})` : ''} and download once it has succeeded.`;
213
+ case 'job_failed':
214
+ return 'The job failed or was cancelled, so it has no audio. athanlab_get_job shows why; create a new job to try again.';
215
+ case 'job_finished':
216
+ return 'The job already finished; there is nothing to cancel. Download it with athanlab_download_audio if it succeeded.';
217
+ case 'audio_expired':
218
+ return 'Audio is deleted 30 days after a job is created. Create a new job to get it again.';
219
+ case 'payload_too_large':
220
+ return 'The request is too large. Send a shorter text (at most 5,000 characters per job).';
221
+ case 'max_chars_exceeded':
222
+ return 'This call exceeds ATHANLAB_MAX_CHARS_PER_CALL, the safety cap configured for this MCP server. Split the text into smaller calls, or raise the cap in the server configuration.';
223
+ case 'confirmation_required':
224
+ return 'Show the quote to the user, then call again with confirm: true to create the jobs.';
225
+ case 'timeout':
226
+ return e.jobId
227
+ ? `The job is still running. Do NOT start it again (that would pay twice): check it later with athanlab_get_job (job_id ${e.jobId}) and fetch the file with athanlab_download_audio.`
228
+ : 'The request timed out. Try again.';
229
+ case 'input_rejected':
230
+ return 'The text could not be turned into speech; the characters were refunded. Change the text (see the athanlab-writing-guide) before trying again.';
231
+ case 'generation_failed':
232
+ case 'interrupted':
233
+ return 'The job failed on AthanLab\'s side and was refunded in full. Submitting it again may succeed.';
234
+ case 'cancelled':
235
+ return 'The job was cancelled; the unprocessed share was refunded. Create a new job if you still need the audio.';
236
+ case 'invalid_job_id':
237
+ return 'A job id is 32 lowercase hex characters, as returned by athanlab_speak or athanlab_list_jobs.';
238
+ case 'invalid_input':
239
+ return 'Fix the input described in the message and try again.';
240
+ case 'unsupported_media_type':
241
+ return 'This server sent a request the API could not read. Please report it (with the request_id).';
242
+ case 'batch_unresolved':
243
+ return 'Nothing new was created. An earlier batch of this script (whose creation was never confirmed) may still be admitting lines. Run the call again with the lines exactly as they were to re-attach to it, or wait until it has finished (batches admit lines for up to 24 hours) before changing them; contact support@athanlab.com with the request_id if it persists.';
244
+ case 'script_running':
245
+ return `Do not run the same script twice at once (it would pay for its lines twice). Wait for the other athanlab_speak_script call to return. If it was abandoned, call again with the same arguments in ${wait}: once the other run has ended this call picks up where it stopped — finished lines are skipped and running jobs are followed, never paid twice.`;
246
+ case 'wav_mismatch':
247
+ return 'The line files have different audio formats, so they cannot be joined into one WAV. The per-line files and manifest.json are complete; mix them in an editor instead.';
248
+ case 'file_error':
249
+ return 'Check that ATHANLAB_OUTPUT_DIR is writable and has free space.';
250
+ default:
251
+ if (e.retryable)
252
+ return `Temporary problem. Try again in ${wait}.`;
253
+ return 'This request cannot succeed as sent. Read the message, change the request, then try again.';
254
+ }
255
+ }
256
+ /** Human-readable block for a tool's text content. */
257
+ export function formatError(e) {
258
+ const lines = [
259
+ `AthanLab error: ${e.code}${e.status ? ` (HTTP ${e.status})` : ''}`,
260
+ e.message,
261
+ `Retryable: ${e.retryable ? 'yes' : 'no'}${e.retryAfterSeconds !== null ? ` (Retry-After: ${e.retryAfterSeconds} s)` : ''}`,
262
+ ];
263
+ if (e.jobId)
264
+ lines.push(`Job ID: ${e.jobId}`);
265
+ if (e.param)
266
+ lines.push(`Parameter: ${e.param}`);
267
+ if (e.requestId)
268
+ lines.push(`Request ID: ${e.requestId}`);
269
+ lines.push(`Action: ${e.action}`);
270
+ if (e.docUrl)
271
+ lines.push(`Docs: ${e.docUrl}`);
272
+ return lines.join('\n');
273
+ }
274
+ /** Anything thrown → AthanLabError, without leaking stack traces into tool output. */
275
+ export function toAthanLabError(err) {
276
+ if (err instanceof AthanLabError)
277
+ return err;
278
+ if (err instanceof Error && (err.name === 'AbortError' || err.name === 'TimeoutError')) {
279
+ return new AthanLabError({ code: 'timeout', message: 'The operation was cancelled or timed out.', source: 'client', retryable: true });
280
+ }
281
+ const message = err instanceof Error ? err.message : String(err);
282
+ return new AthanLabError({ code: 'internal_client_error', message: `Unexpected error in the AthanLab MCP server: ${message}`, source: 'client' });
283
+ }
284
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ import { isRecord } from './errors.js';
2
+ import { USER_AGENT } from '../version.js';
3
+ export const NO_FEATURES = Object.freeze({
4
+ speed: null,
5
+ replacements: null,
6
+ batch: false,
7
+ timing: false,
8
+ errorCatalog: new Map(),
9
+ apiVersion: null,
10
+ });
11
+ const DEFAULT_SPEED = { min: 0.8, max: 1.2 };
12
+ const DEFAULT_REPLACEMENTS = { maxRules: 50, fromMaxLength: 50, toMaxLength: 100 };
13
+ function schemaOf(spec, name) {
14
+ const components = spec.components;
15
+ if (!isRecord(components) || !isRecord(components.schemas))
16
+ return null;
17
+ const schema = components.schemas[name];
18
+ return isRecord(schema) ? schema : null;
19
+ }
20
+ function propertiesOf(schema) {
21
+ return schema && isRecord(schema.properties) ? schema.properties : {};
22
+ }
23
+ /** The non-null branch of a nullable property (`anyOf: [{…}, {type: 'null'}]`), or the property itself. */
24
+ function concrete(prop) {
25
+ if (!isRecord(prop))
26
+ return null;
27
+ for (const key of ['anyOf', 'oneOf']) {
28
+ const branches = prop[key];
29
+ if (Array.isArray(branches)) {
30
+ const branch = branches.find(b => isRecord(b) && b.type !== 'null');
31
+ if (isRecord(branch))
32
+ return { ...prop, ...branch };
33
+ }
34
+ }
35
+ return prop;
36
+ }
37
+ function num(value, fallback) {
38
+ return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
39
+ }
40
+ export function detectFeatures(spec) {
41
+ if (!isRecord(spec))
42
+ return { ...NO_FEATURES, errorCatalog: new Map() };
43
+ const request = propertiesOf(schemaOf(spec, 'CreateSpeechRequest'));
44
+ const audio = propertiesOf(schemaOf(spec, 'SpeechAudio'));
45
+ let speed = null;
46
+ const speedProp = concrete(request.speed);
47
+ if (speedProp) {
48
+ speed = {
49
+ min: num(speedProp.minimum, DEFAULT_SPEED.min),
50
+ max: num(speedProp.maximum, DEFAULT_SPEED.max),
51
+ };
52
+ if (!(speed.min > 0 && speed.min < speed.max))
53
+ speed = { ...DEFAULT_SPEED };
54
+ }
55
+ let replacements = null;
56
+ const replProp = concrete(request.replacements);
57
+ if (replProp) {
58
+ const items = concrete(replProp.items);
59
+ const itemProps = propertiesOf(items);
60
+ replacements = {
61
+ maxRules: num(replProp.maxItems, DEFAULT_REPLACEMENTS.maxRules),
62
+ fromMaxLength: num(concrete(itemProps.from)?.maxLength, DEFAULT_REPLACEMENTS.fromMaxLength),
63
+ toMaxLength: num(concrete(itemProps.to)?.maxLength, DEFAULT_REPLACEMENTS.toMaxLength),
64
+ };
65
+ }
66
+ const paths = isRecord(spec.paths) ? spec.paths : {};
67
+ const batchPath = paths['/speech/batch'];
68
+ const batch = isRecord(batchPath) && isRecord(batchPath.post);
69
+ const timing = 'segments' in audio || 'speech_start_seconds' in audio;
70
+ const errorCatalog = new Map();
71
+ const codes = spec['x-error-codes'];
72
+ if (Array.isArray(codes)) {
73
+ for (const entry of codes) {
74
+ if (isRecord(entry) && typeof entry.code === 'string' && typeof entry.message === 'string') {
75
+ errorCatalog.set(entry.code, {
76
+ status: num(entry.status, 500),
77
+ type: typeof entry.type === 'string' ? entry.type : 'api_error',
78
+ retryable: entry.retryable === true,
79
+ message: entry.message,
80
+ });
81
+ }
82
+ }
83
+ }
84
+ const info = isRecord(spec.info) ? spec.info : {};
85
+ return {
86
+ speed,
87
+ replacements,
88
+ batch,
89
+ timing,
90
+ errorCatalog,
91
+ apiVersion: typeof info.version === 'string' ? info.version : null,
92
+ };
93
+ }
94
+ /** Fetch and detect. Never throws: an unreachable document means "no Phase B features". */
95
+ export async function loadFeatures(apiBase, opts) {
96
+ const fetchImpl = opts.fetch ?? ((input, init) => fetch(input, init));
97
+ try {
98
+ const res = await fetchImpl(`${apiBase}/openapi.json`, {
99
+ headers: { Accept: 'application/json', 'User-Agent': USER_AGENT },
100
+ signal: AbortSignal.timeout(opts.timeoutMs ?? 5_000),
101
+ });
102
+ if (!res.ok) {
103
+ opts.logger.warn('could not read the API description; optional features stay off', { status: res.status });
104
+ return { ...NO_FEATURES, errorCatalog: new Map() };
105
+ }
106
+ const features = detectFeatures(await res.json());
107
+ opts.logger.info('API features detected', {
108
+ api_version: features.apiVersion,
109
+ speed: features.speed !== null,
110
+ replacements: features.replacements !== null,
111
+ batch: features.batch,
112
+ timing: features.timing,
113
+ });
114
+ return features;
115
+ }
116
+ catch (err) {
117
+ opts.logger.warn('could not read the API description; optional features stay off', {
118
+ error: err instanceof Error ? err.message : String(err),
119
+ });
120
+ return { ...NO_FEATURES, errorCatalog: new Map() };
121
+ }
122
+ }
123
+ //# sourceMappingURL=features.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features.js","sourceRoot":"","sources":["../../src/api/features.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export const OUTPUT_FORMATS = ['wav', 'mp3'];
2
+ export const JOB_STATUSES = ['processing', 'succeeded', 'failed', 'cancelled'];
3
+ /**
4
+ * Exhaustive by construction: adding a mode to the API's enum (and
5
+ * regenerating the types) fails the typecheck here until it is listed.
6
+ */
7
+ const NUMBER_MODE_SET = {
8
+ smart: true,
9
+ place: true,
10
+ digits: true,
11
+ english: true,
12
+ english_digits: true,
13
+ };
14
+ export const NUMBER_MODES = Object.keys(NUMBER_MODE_SET);
15
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AA+BA,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,KAAK,CAA4C,CAAA;AACvF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAyC,CAAA;AAEtH;;;GAGG;AACH,MAAM,eAAe,GAA6B;IAChD,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,IAAI;IACb,cAAc,EAAE,IAAI;CACrB,CAAA;AACD,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAkC,CAAA"}