@akoskomuves/appstoreconnect-mcp 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/LICENSE +21 -0
  3. package/README.md +158 -0
  4. package/data/apple-music-prices.json +78 -0
  5. package/dist/auth.d.ts +9 -0
  6. package/dist/auth.d.ts.map +1 -0
  7. package/dist/auth.js +33 -0
  8. package/dist/auth.js.map +1 -0
  9. package/dist/client.d.ts +6 -0
  10. package/dist/client.d.ts.map +1 -0
  11. package/dist/client.js +75 -0
  12. package/dist/client.js.map +1 -0
  13. package/dist/clients.d.ts +31 -0
  14. package/dist/clients.d.ts.map +1 -0
  15. package/dist/clients.js +88 -0
  16. package/dist/clients.js.map +1 -0
  17. package/dist/config.d.ts +7 -0
  18. package/dist/config.d.ts.map +1 -0
  19. package/dist/config.js +29 -0
  20. package/dist/config.js.map +1 -0
  21. package/dist/digest.d.ts +13 -0
  22. package/dist/digest.d.ts.map +1 -0
  23. package/dist/digest.js +154 -0
  24. package/dist/digest.js.map +1 -0
  25. package/dist/doctor.d.ts +2 -0
  26. package/dist/doctor.d.ts.map +1 -0
  27. package/dist/doctor.js +139 -0
  28. package/dist/doctor.js.map +1 -0
  29. package/dist/domains/apps.d.ts +4 -0
  30. package/dist/domains/apps.d.ts.map +1 -0
  31. package/dist/domains/apps.js +40 -0
  32. package/dist/domains/apps.js.map +1 -0
  33. package/dist/domains/ppp.d.ts +6 -0
  34. package/dist/domains/ppp.d.ts.map +1 -0
  35. package/dist/domains/ppp.js +539 -0
  36. package/dist/domains/ppp.js.map +1 -0
  37. package/dist/domains/pricing.d.ts +4 -0
  38. package/dist/domains/pricing.d.ts.map +1 -0
  39. package/dist/domains/pricing.js +55 -0
  40. package/dist/domains/pricing.js.map +1 -0
  41. package/dist/domains/subscriptions.d.ts +4 -0
  42. package/dist/domains/subscriptions.d.ts.map +1 -0
  43. package/dist/domains/subscriptions.js +84 -0
  44. package/dist/domains/subscriptions.js.map +1 -0
  45. package/dist/domains/territories.d.ts +4 -0
  46. package/dist/domains/territories.d.ts.map +1 -0
  47. package/dist/domains/territories.js +21 -0
  48. package/dist/domains/territories.js.map +1 -0
  49. package/dist/errors.d.ts +6 -0
  50. package/dist/errors.d.ts.map +1 -0
  51. package/dist/errors.js +11 -0
  52. package/dist/errors.js.map +1 -0
  53. package/dist/index.d.ts +3 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +98 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/init.d.ts +6 -0
  58. package/dist/init.d.ts.map +1 -0
  59. package/dist/init.js +316 -0
  60. package/dist/init.js.map +1 -0
  61. package/dist/jsonapi.d.ts +62 -0
  62. package/dist/jsonapi.d.ts.map +1 -0
  63. package/dist/jsonapi.js +78 -0
  64. package/dist/jsonapi.js.map +1 -0
  65. package/dist/ppp/index.d.ts +40 -0
  66. package/dist/ppp/index.d.ts.map +1 -0
  67. package/dist/ppp/index.js +85 -0
  68. package/dist/ppp/index.js.map +1 -0
  69. package/dist/schemas.d.ts +10 -0
  70. package/dist/schemas.d.ts.map +1 -0
  71. package/dist/schemas.js +34 -0
  72. package/dist/schemas.js.map +1 -0
  73. package/package.json +79 -0
package/dist/config.js ADDED
@@ -0,0 +1,29 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ function expandHome(path) {
4
+ if (path.startsWith('~/'))
5
+ return path.replace('~', homedir());
6
+ if (path === '~')
7
+ return homedir();
8
+ return path;
9
+ }
10
+ function requireEnv(name) {
11
+ const value = process.env[name];
12
+ if (!value)
13
+ throw new Error(`Missing required environment variable: ${name}`);
14
+ return value;
15
+ }
16
+ export function loadConfig() {
17
+ const issuerId = requireEnv('ASC_ISSUER_ID');
18
+ const keyId = requireEnv('ASC_KEY_ID');
19
+ const privateKeyPath = expandHome(requireEnv('ASC_PRIVATE_KEY_PATH'));
20
+ let privateKey;
21
+ try {
22
+ privateKey = readFileSync(privateKeyPath, 'utf-8');
23
+ }
24
+ catch (err) {
25
+ throw new Error(`Failed to read ASC_PRIVATE_KEY_PATH at ${privateKeyPath}: ${err.message}`);
26
+ }
27
+ return { issuerId, keyId, privateKey };
28
+ }
29
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAQlC,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;IAC/D,IAAI,IAAI,KAAK,GAAG;QAAE,OAAO,OAAO,EAAE,CAAC;IACnC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,IAAI,EAAE,CAAC,CAAC;IAC9E,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,QAAQ,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACvC,MAAM,cAAc,GAAG,UAAU,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC,CAAC;IACtE,IAAI,UAAkB,CAAC;IACvB,IAAI,CAAC;QACH,UAAU,GAAG,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,0CAA0C,cAAc,KAAM,GAAa,CAAC,OAAO,EAAE,CACtF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AACzC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type CollectedPages, type JSONAPIResource } from './jsonapi.js';
2
+ export declare function digestApps(pages: CollectedPages): string;
3
+ export declare function digestSubscriptionGroups(pages: CollectedPages): string;
4
+ export declare function digestSubscriptions(pages: CollectedPages): string;
5
+ export declare function digestSubscriptionPrices(pages: CollectedPages): string;
6
+ export declare function digestSubscriptionPricePoints(pages: CollectedPages): string;
7
+ export declare function digestTerritories(pages: CollectedPages): string;
8
+ /**
9
+ * Single-resource digest: when a tool returns one app/subscription/etc., this
10
+ * pretty-prints the most useful attributes without the JSON:API noise.
11
+ */
12
+ export declare function digestSingle(resource: JSONAPIResource, label: string): string;
13
+ //# sourceMappingURL=digest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EAGnB,KAAK,eAAe,EAErB,MAAM,cAAc,CAAC;AA2BtB,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAcxD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAItE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAkBjE;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAsCtE;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAsB3E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAK/D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAa7E"}
package/dist/digest.js ADDED
@@ -0,0 +1,154 @@
1
+ import { buildIncludedIndex, formatTable, lookupIncluded, } from './jsonapi.js';
2
+ function attr(resource, key) {
3
+ return resource.attributes?.[key];
4
+ }
5
+ function rel(resource, key) {
6
+ const r = resource.relationships?.[key];
7
+ if (!r?.data)
8
+ return undefined;
9
+ if (Array.isArray(r.data))
10
+ return r.data[0];
11
+ return r.data;
12
+ }
13
+ function s(v) {
14
+ if (v === null || v === undefined)
15
+ return '';
16
+ if (typeof v === 'string')
17
+ return v;
18
+ if (typeof v === 'number' || typeof v === 'boolean')
19
+ return String(v);
20
+ return JSON.stringify(v);
21
+ }
22
+ function summaryFooter(pages, label) {
23
+ const count = pages.data.length;
24
+ const total = pages.total ?? count;
25
+ const more = pages.truncated ? ` (truncated — set raw:true or pass maxItems to fetch more)` : '';
26
+ return `${count} ${label}${count === total ? '' : ` of ${total}`}${more}`;
27
+ }
28
+ export function digestApps(pages) {
29
+ const columns = [
30
+ { header: 'NAME' },
31
+ { header: 'BUNDLE_ID' },
32
+ { header: 'SKU' },
33
+ { header: 'ID' },
34
+ ];
35
+ const rows = pages.data.map((app) => [
36
+ s(attr(app, 'name')),
37
+ s(attr(app, 'bundleId')),
38
+ s(attr(app, 'sku')),
39
+ app.id,
40
+ ]);
41
+ return `${summaryFooter(pages, 'apps')}\n\n${formatTable(columns, rows)}`;
42
+ }
43
+ export function digestSubscriptionGroups(pages) {
44
+ const columns = [{ header: 'REFERENCE_NAME' }, { header: 'ID' }];
45
+ const rows = pages.data.map((g) => [s(attr(g, 'referenceName')), g.id]);
46
+ return `${summaryFooter(pages, 'groups')}\n\n${formatTable(columns, rows)}`;
47
+ }
48
+ export function digestSubscriptions(pages) {
49
+ const columns = [
50
+ { header: 'NAME' },
51
+ { header: 'PRODUCT_ID' },
52
+ { header: 'PERIOD' },
53
+ { header: 'STATE' },
54
+ { header: 'GROUP_LEVEL', align: 'right' },
55
+ { header: 'ID' },
56
+ ];
57
+ const rows = pages.data.map((sub) => [
58
+ s(attr(sub, 'name')),
59
+ s(attr(sub, 'productId')),
60
+ s(attr(sub, 'subscriptionPeriod')),
61
+ s(attr(sub, 'state')),
62
+ s(attr(sub, 'groupLevel')),
63
+ sub.id,
64
+ ]);
65
+ return `${summaryFooter(pages, 'subscriptions')}\n\n${formatTable(columns, rows)}`;
66
+ }
67
+ export function digestSubscriptionPrices(pages) {
68
+ const index = buildIncludedIndex(pages.included);
69
+ const columns = [
70
+ { header: 'TERR' },
71
+ { header: 'CCY' },
72
+ { header: 'AMOUNT', align: 'right' },
73
+ { header: 'STATE' },
74
+ { header: 'START_DATE' },
75
+ { header: 'PRESERVE' },
76
+ { header: 'PRICE_ID' },
77
+ { header: 'POINT_ID' },
78
+ ];
79
+ const rows = pages.data.map((price) => {
80
+ const territoryRel = rel(price, 'territory');
81
+ const pricePointRel = rel(price, 'subscriptionPricePoint');
82
+ const territory = lookupIncluded(index, 'territories', territoryRel?.id);
83
+ const pricePoint = lookupIncluded(index, 'subscriptionPricePoints', pricePointRel?.id);
84
+ const startDate = attr(price, 'startDate');
85
+ // ASC's SubscriptionPrice attribute is `preserved` (read-side); the POST
86
+ // body uses `preserveCurrentPrice` (write-side). Different names, same idea.
87
+ const preserve = attr(price, 'preserved');
88
+ const state = startDate ? 'pending' : 'active';
89
+ return [
90
+ s(territoryRel?.id),
91
+ s(territory ? attr(territory, 'currency') : ''),
92
+ s(pricePoint ? attr(pricePoint, 'customerPrice') : ''),
93
+ state,
94
+ s(startDate ?? ''),
95
+ s(preserve ?? false),
96
+ price.id,
97
+ s(pricePointRel?.id ?? ''),
98
+ ];
99
+ });
100
+ rows.sort((a, b) => (a[0] ?? '').localeCompare(b[0] ?? ''));
101
+ const pending = rows.filter((r) => r[3] === 'pending').length;
102
+ const summary = `${summaryFooter(pages, 'prices')} — ${pending} pending`;
103
+ return `${summary}\n\n${formatTable(columns, rows)}`;
104
+ }
105
+ export function digestSubscriptionPricePoints(pages) {
106
+ const index = buildIncludedIndex(pages.included);
107
+ const columns = [
108
+ { header: 'CCY' },
109
+ { header: 'CUSTOMER_PRICE', align: 'right' },
110
+ { header: 'PROCEEDS', align: 'right' },
111
+ { header: 'PROCEEDS_Y2', align: 'right' },
112
+ { header: 'POINT_ID' },
113
+ ];
114
+ const rows = pages.data.map((p) => {
115
+ const territoryRel = rel(p, 'territory');
116
+ const territory = lookupIncluded(index, 'territories', territoryRel?.id);
117
+ return [
118
+ s(territory ? attr(territory, 'currency') : territoryRel?.id),
119
+ s(attr(p, 'customerPrice')),
120
+ s(attr(p, 'proceeds')),
121
+ s(attr(p, 'proceedsYear2')),
122
+ p.id,
123
+ ];
124
+ });
125
+ rows.sort((a, b) => Number(a[1] ?? 0) - Number(b[1] ?? 0));
126
+ return `${summaryFooter(pages, 'price points')}\n\n${formatTable(columns, rows)}`;
127
+ }
128
+ export function digestTerritories(pages) {
129
+ const columns = [{ header: 'CODE' }, { header: 'CURRENCY' }];
130
+ const rows = pages.data.map((t) => [t.id, s(attr(t, 'currency'))]);
131
+ rows.sort((a, b) => (a[0] ?? '').localeCompare(b[0] ?? ''));
132
+ return `${summaryFooter(pages, 'territories')}\n\n${formatTable(columns, rows)}`;
133
+ }
134
+ /**
135
+ * Single-resource digest: when a tool returns one app/subscription/etc., this
136
+ * pretty-prints the most useful attributes without the JSON:API noise.
137
+ */
138
+ export function digestSingle(resource, label) {
139
+ const lines = [`${label} ${resource.id}`];
140
+ if (resource.attributes) {
141
+ for (const [k, v] of Object.entries(resource.attributes)) {
142
+ if (v === null || v === undefined)
143
+ continue;
144
+ if (typeof v === 'object') {
145
+ lines.push(` ${k}: ${JSON.stringify(v)}`);
146
+ }
147
+ else {
148
+ lines.push(` ${k}: ${String(v)}`);
149
+ }
150
+ }
151
+ }
152
+ return lines.join('\n');
153
+ }
154
+ //# sourceMappingURL=digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digest.js","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function main(): Promise<void>;
2
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAmIA,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA0B1C"}
package/dist/doctor.js ADDED
@@ -0,0 +1,139 @@
1
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { importPKCS8 } from 'jose';
5
+ import { TokenProvider } from './auth.js';
6
+ import { detectClients, listClients, readServer } from './clients.js';
7
+ const HOME = homedir();
8
+ const KEY_DIR = join(HOME, '.appstore');
9
+ const SERVER_NAME = 'appstoreconnect';
10
+ function fmt(r) {
11
+ const mark = r.ok ? '✓' : '✗';
12
+ return ` ${mark} ${r.label}${r.detail ? ` — ${r.detail}` : ''}`;
13
+ }
14
+ function info(label, detail) {
15
+ return ` · ${label}${detail ? ` — ${detail}` : ''}`;
16
+ }
17
+ async function checkKeyDir() {
18
+ const out = [];
19
+ if (!existsSync(KEY_DIR)) {
20
+ out.push({
21
+ ok: false,
22
+ label: `${KEY_DIR} not found`,
23
+ detail: 'run `appstoreconnect-mcp init` to set it up',
24
+ });
25
+ return out;
26
+ }
27
+ const stat = statSync(KEY_DIR);
28
+ const mode = stat.mode & 0o777;
29
+ out.push({
30
+ ok: mode === 0o700,
31
+ label: `${KEY_DIR} permissions`,
32
+ detail: `mode ${mode.toString(8)}${mode === 0o700 ? '' : ' (recommend chmod 700)'}`,
33
+ });
34
+ const files = readdirSync(KEY_DIR).filter((f) => f.endsWith('.p8'));
35
+ if (files.length === 0) {
36
+ out.push({ ok: false, label: 'No .p8 keys found in ~/.appstore' });
37
+ return out;
38
+ }
39
+ for (const f of files) {
40
+ const path = join(KEY_DIR, f);
41
+ const fileMode = statSync(path).mode & 0o777;
42
+ let parsed = false;
43
+ try {
44
+ const text = readFileSync(path, 'utf-8');
45
+ await importPKCS8(text, 'ES256');
46
+ parsed = true;
47
+ }
48
+ catch {
49
+ parsed = false;
50
+ }
51
+ out.push({
52
+ ok: parsed && fileMode === 0o600,
53
+ label: f,
54
+ detail: `mode ${fileMode.toString(8)}, ${parsed ? 'parses as ES256 PKCS8' : 'failed to parse'}`,
55
+ });
56
+ }
57
+ return out;
58
+ }
59
+ function checkClients() {
60
+ const detected = detectClients();
61
+ const all = listClients();
62
+ const out = [];
63
+ out.push({
64
+ ok: detected.length > 0,
65
+ label: 'MCP clients detected',
66
+ detail: detected.length === 0 ? 'no client configs found' : detected.map((c) => c.label).join(', '),
67
+ });
68
+ for (const client of all) {
69
+ const entry = readServer(client, SERVER_NAME);
70
+ if (!entry)
71
+ continue;
72
+ const env = entry.env ?? {};
73
+ const cmd = `${entry.command}${entry.args ? ` ${entry.args.join(' ')}` : ''}`;
74
+ const envParts = ['ASC_ISSUER_ID', 'ASC_KEY_ID', 'ASC_PRIVATE_KEY_PATH'].map((k) => `${k}=${env[k] ? 'set' : 'MISSING'}`);
75
+ const ok = envParts.every((p) => p.endsWith('=set'));
76
+ out.push({
77
+ ok,
78
+ label: `${client.label} → ${SERVER_NAME}`,
79
+ detail: `${cmd} (${envParts.join(', ')})`,
80
+ });
81
+ }
82
+ return out;
83
+ }
84
+ async function checkAuth() {
85
+ const issuerId = process.env['ASC_ISSUER_ID'];
86
+ const keyId = process.env['ASC_KEY_ID'];
87
+ const keyPath = process.env['ASC_PRIVATE_KEY_PATH'];
88
+ if (!issuerId || !keyId || !keyPath) {
89
+ return null;
90
+ }
91
+ const expanded = keyPath.startsWith('~/') ? keyPath.replace('~', HOME) : keyPath;
92
+ if (!existsSync(expanded)) {
93
+ return { ok: false, label: 'Live auth check', detail: `key not found at ${expanded}` };
94
+ }
95
+ try {
96
+ const tokens = new TokenProvider({
97
+ issuerId,
98
+ keyId,
99
+ privateKey: readFileSync(expanded, 'utf-8'),
100
+ });
101
+ const token = await tokens.getToken();
102
+ const res = await fetch('https://api.appstoreconnect.apple.com/v1/apps?limit=1', {
103
+ headers: { authorization: `Bearer ${token}` },
104
+ });
105
+ if (!res.ok) {
106
+ return {
107
+ ok: false,
108
+ label: 'Live auth check',
109
+ detail: `App Store Connect returned ${res.status}`,
110
+ };
111
+ }
112
+ return { ok: true, label: 'Live auth check', detail: 'JWT signed and accepted' };
113
+ }
114
+ catch (err) {
115
+ return { ok: false, label: 'Live auth check', detail: err.message };
116
+ }
117
+ }
118
+ export async function main() {
119
+ console.log('\nappstoreconnect-mcp — doctor\n');
120
+ console.log('Key directory:');
121
+ for (const r of await checkKeyDir())
122
+ console.log(fmt(r));
123
+ console.log('\nMCP client integrations:');
124
+ for (const r of checkClients())
125
+ console.log(fmt(r));
126
+ const liveAuth = await checkAuth();
127
+ console.log('\nLive auth:');
128
+ if (liveAuth) {
129
+ console.log(fmt(liveAuth));
130
+ }
131
+ else {
132
+ console.log(info('skipped', 'set ASC_ISSUER_ID/ASC_KEY_ID/ASC_PRIVATE_KEY_PATH env vars to verify against the live API'));
133
+ }
134
+ console.log('\nNext steps:');
135
+ console.log(' - First-time setup: appstoreconnect-mcp init');
136
+ console.log(' - Use it from a client: ask "use appstoreconnect to list my apps"');
137
+ console.log(' - Issues: https://github.com/akoskomuves/appstoreconnect-mcp/issues\n');
138
+ }
139
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ASCClient } from '../client.js';
3
+ export declare function registerApps(server: McpServer, client: ASCClient): void;
4
+ //# sourceMappingURL=apps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/domains/apps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAQ9C,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA4CvE"}
@@ -0,0 +1,40 @@
1
+ import { z } from 'zod';
2
+ import { digestApps, digestSingle } from '../digest.js';
3
+ import { paginate } from '../jsonapi.js';
4
+ import { AppIdSchema, BundleIdSchema } from '../schemas.js';
5
+ const APP_FIELDS = 'name,bundleId,sku,primaryLocale,contentRightsDeclaration';
6
+ export function registerApps(server, client) {
7
+ server.registerTool('asc_list_apps', {
8
+ title: 'List apps',
9
+ description: 'List apps on the App Store Connect account. Returns a compact table by default; pass raw:true to get the full JSON:API response.',
10
+ inputSchema: {
11
+ bundleId: BundleIdSchema.optional(),
12
+ maxItems: z.number().int().positive().max(2000).default(1000),
13
+ raw: z.boolean().default(false),
14
+ },
15
+ }, async ({ bundleId, maxItems, raw }) => {
16
+ const params = new URLSearchParams();
17
+ if (bundleId)
18
+ params.set('filter[bundleId]', bundleId);
19
+ params.set('fields[apps]', APP_FIELDS);
20
+ params.set('limit', '200');
21
+ const pages = await paginate(client, `/v1/apps?${params.toString()}`, maxItems);
22
+ const text = raw ? JSON.stringify(pages, null, 2) : digestApps(pages);
23
+ return { content: [{ type: 'text', text }] };
24
+ });
25
+ server.registerTool('asc_get_app', {
26
+ title: 'Get app',
27
+ description: 'Fetch a single app by its App Store Connect ID.',
28
+ inputSchema: {
29
+ appId: AppIdSchema,
30
+ raw: z.boolean().default(false),
31
+ },
32
+ }, async ({ appId, raw }) => {
33
+ const params = new URLSearchParams();
34
+ params.set('fields[apps]', APP_FIELDS);
35
+ const data = await client.request(`/v1/apps/${encodeURIComponent(appId)}?${params.toString()}`);
36
+ const text = raw ? JSON.stringify(data, null, 2) : digestSingle(data.data, 'App');
37
+ return { content: [{ type: 'text', text }] };
38
+ });
39
+ }
40
+ //# sourceMappingURL=apps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/domains/apps.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE5D,MAAM,UAAU,GAAG,0DAA0D,CAAC;AAE9E,MAAM,UAAU,YAAY,CAAC,MAAiB,EAAE,MAAiB;IAC/D,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,KAAK,EAAE,WAAW;QAClB,WAAW,EACT,kIAAkI;QACpI,WAAW,EAAE;YACX,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE;YACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;YAC7D,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;SAChC;KACF,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE;QACpC,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QACrC,IAAI,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;QACvD,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QACvC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC3B,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,YAAY,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;QAChF,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACtE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC/C,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;QACE,KAAK,EAAE,SAAS;QAChB,WAAW,EAAE,iDAAiD;QAC9D,WAAW,EAAE;YACX,KAAK,EAAE,WAAW;YAClB,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;SAChC;KACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE;QACvB,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAC/B,YAAY,kBAAkB,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAC7D,CAAC;QACF,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC/C,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ASCClient } from '../client.js';
3
+ /** Run async tasks with a fixed concurrency limit. Returns results in order. */
4
+ export declare function concurrentMap<T, R>(items: T[], concurrency: number, worker: (item: T, index: number) => Promise<R>): Promise<R[]>;
5
+ export declare function registerPpp(server: McpServer, client: ASCClient): void;
6
+ //# sourceMappingURL=ppp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ppp.d.ts","sourceRoot":"","sources":["../../src/domains/ppp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AA+V9C,gFAAgF;AAChF,wBAAsB,aAAa,CAAC,CAAC,EAAE,CAAC,EACtC,KAAK,EAAE,CAAC,EAAE,EACV,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAC7C,OAAO,CAAC,CAAC,EAAE,CAAC,CAcd;AAgDD,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA4RtE"}