sensor-tower-mcp 1.0.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/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # sensor-tower-mcp
2
+
3
+ MCP (Model Context Protocol) server for SensorTower API - App Intelligence, Downloads, Revenue, Active Users, and more.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npx sensor-tower-mcp
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ Add to your MCP client configuration (e.g., Claude Desktop):
14
+
15
+ ```json
16
+ {
17
+ "mcpServers": {
18
+ "sensor-tower-mcp": {
19
+ "command": "npx",
20
+ "args": ["-y", "sensor-tower-mcp"],
21
+ "env": {
22
+ "SENSOR_TOWER_AUTH_TOKEN": "your_auth_token_here"
23
+ }
24
+ }
25
+ }
26
+ }
27
+ ```
28
+
29
+ ## Available Tools
30
+
31
+ ### App Discovery
32
+ - **discover_app_id** - Parse App Store/Google Play URL to extract app ID, or get instructions for finding app ID by name
33
+
34
+ ### App Intelligence
35
+ - **get_app_info** - Get app metadata (name, publisher, categories, ratings, etc.)
36
+ - **get_top_in_app_purchases** - Get top in-app purchases for iOS apps
37
+
38
+ ### Downloads & Revenue
39
+ - **get_sales_report** - Get download and revenue estimates by country and date
40
+ - **get_downloads_by_source** - Get downloads breakdown by source (organic, paid, browser)
41
+
42
+ ### User Metrics
43
+ - **get_active_users** - Get active user estimates (DAU/WAU/MAU)
44
+ - **get_retention** - Get app retention data (Day 1 to Day 90)
45
+
46
+ ### Category Rankings
47
+ - **get_category_ranking_history** - Get historical category ranking
48
+ - **get_category_ranking_summary** - Get current category ranking summary
49
+
50
+ ### Advertising Intelligence
51
+ - **get_ad_network_analysis** - Get advertising share of voice (SOV) time series
52
+ - **get_ad_network_rank** - Get advertising rank across networks and countries
53
+
54
+ ### Reference
55
+ - **list_categories** - List available iOS category IDs
56
+ - **list_ad_networks** - List available ad networks
57
+
58
+ ## Prompts
59
+
60
+ ### analyze_app
61
+ Comprehensive app analysis workflow - automatically finds app ID and retrieves key metrics.
62
+
63
+ ```
64
+ Arguments:
65
+ - app_name_or_url: App name, App Store URL, or Google Play URL
66
+ - platform: ios or android (required if providing app name)
67
+ ```
68
+
69
+ ### compare_apps
70
+ Compare multiple apps on key metrics.
71
+
72
+ ```
73
+ Arguments:
74
+ - apps: Comma-separated list of app names or IDs
75
+ - platform: ios or android
76
+ ```
77
+
78
+ ## App ID Discovery
79
+
80
+ The server supports intelligent App ID discovery:
81
+
82
+ 1. **From URLs**: Automatically extracts IDs from App Store or Google Play URLs
83
+ - iOS: `https://apps.apple.com/.../id284882215` → `284882215`
84
+ - Android: `https://play.google.com/store/apps/details?id=com.example.app` → `com.example.app`
85
+
86
+ 2. **From Names**: Provides search queries to find official store pages
87
+ - Use web search (DuckDuckGo, Tavily, etc.) to find the store URL
88
+ - Extract the App ID from the URL
89
+
90
+ ## Examples
91
+
92
+ ### Get app info
93
+ ```
94
+ Use get_app_info with:
95
+ - os: "ios"
96
+ - app_ids: ["284882215"]
97
+ - country: "US"
98
+ ```
99
+
100
+ ### Get active users (DAU)
101
+ ```
102
+ Use get_active_users with:
103
+ - os: "ios"
104
+ - app_ids: ["284882215"]
105
+ - time_period: "day"
106
+ - start_date: "2024-01-01"
107
+ - end_date: "2024-01-31"
108
+ - countries: ["US"]
109
+ ```
110
+
111
+ ### Get sales report
112
+ ```
113
+ Use get_sales_report with:
114
+ - os: "ios"
115
+ - app_ids: ["284882215"]
116
+ - date_granularity: "daily"
117
+ - start_date: "2024-01-01"
118
+ - end_date: "2024-01-31"
119
+ - countries: ["US", "GB", "JP"]
120
+ ```
121
+
122
+ ## API Rate Limits
123
+
124
+ SensorTower API has a rate limit of 6 requests per second. The server does not implement rate limiting internally, so be mindful of request frequency.
125
+
126
+ ## License
127
+
128
+ MIT
@@ -0,0 +1,82 @@
1
+ import { SensorTowerConfig, OsType, TimePeriod, DateGranularity, AdIntelPeriod } from './types.js';
2
+ export declare class SensorTowerClient {
3
+ private authToken;
4
+ private baseUrl;
5
+ constructor(config: SensorTowerConfig);
6
+ private request;
7
+ getApps(os: 'ios' | 'android', appIds: string[], country?: string): Promise<unknown>;
8
+ getTopInAppPurchases(appIds: string[], country?: string): Promise<unknown>;
9
+ getSalesReportEstimates(os: OsType, options: {
10
+ appIds?: string[];
11
+ publisherIds?: string[];
12
+ unifiedAppIds?: string[];
13
+ unifiedPublisherIds?: string[];
14
+ categories?: string[];
15
+ countries?: string[];
16
+ dateGranularity: DateGranularity;
17
+ startDate: string;
18
+ endDate: string;
19
+ dataModel?: string;
20
+ }): Promise<unknown>;
21
+ getCompactSalesReport(os: 'ios' | 'android', options: {
22
+ appIds?: string[];
23
+ publisherIds?: string[];
24
+ unifiedAppIds?: string[];
25
+ unifiedPublisherIds?: string[];
26
+ categories?: string[];
27
+ countries?: string[];
28
+ dateGranularity?: DateGranularity;
29
+ startDate: string;
30
+ endDate: string;
31
+ dataModel?: string;
32
+ }): Promise<unknown>;
33
+ getActiveUsers(os: OsType, options: {
34
+ appIds: string[];
35
+ timePeriod: TimePeriod;
36
+ startDate: string;
37
+ endDate: string;
38
+ countries?: string[];
39
+ dataModel?: string;
40
+ }): Promise<unknown>;
41
+ getCategoryHistory(os: 'ios' | 'android', options: {
42
+ appIds: string[];
43
+ category: string;
44
+ chartTypeIds: string[];
45
+ countries?: string[];
46
+ startDate: string;
47
+ endDate: string;
48
+ isHourly?: boolean;
49
+ }): Promise<unknown>;
50
+ getCategoryRankingSummary(os: 'ios' | 'android', appId: string, country?: string): Promise<unknown>;
51
+ getNetworkAnalysis(os: OsType, options: {
52
+ appIds: string[];
53
+ startDate: string;
54
+ endDate: string;
55
+ period: AdIntelPeriod;
56
+ networks?: string[];
57
+ countries?: string[];
58
+ }): Promise<unknown>;
59
+ getNetworkAnalysisRank(os: OsType, options: {
60
+ appIds: string[];
61
+ startDate: string;
62
+ endDate: string;
63
+ period: 'day' | 'week';
64
+ networks?: string[];
65
+ countries?: string[];
66
+ }): Promise<unknown>;
67
+ getRetention(os: 'ios' | 'android', options: {
68
+ appIds: string[];
69
+ dateGranularity: 'all_time' | 'quarterly';
70
+ startDate: string;
71
+ endDate?: string;
72
+ country?: string;
73
+ }): Promise<unknown>;
74
+ getDownloadsBySources(os: OsType, options: {
75
+ appIds: string[];
76
+ countries: string[];
77
+ dateGranularity?: 'daily' | 'monthly';
78
+ startDate: string;
79
+ endDate: string;
80
+ }): Promise<unknown>;
81
+ }
82
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,137 @@
1
+ const DEFAULT_BASE_URL = 'https://api.sensortower.com';
2
+ export class SensorTowerClient {
3
+ authToken;
4
+ baseUrl;
5
+ constructor(config) {
6
+ this.authToken = config.authToken;
7
+ this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
8
+ }
9
+ async request(endpoint, params) {
10
+ const url = new URL(endpoint, this.baseUrl);
11
+ url.searchParams.set('auth_token', this.authToken);
12
+ for (const [key, value] of Object.entries(params)) {
13
+ if (value === undefined)
14
+ continue;
15
+ if (Array.isArray(value)) {
16
+ value.forEach(v => url.searchParams.append(`${key}[]`, v));
17
+ }
18
+ else {
19
+ url.searchParams.set(key, value);
20
+ }
21
+ }
22
+ const response = await fetch(url.toString(), {
23
+ headers: { 'Accept': 'application/json' }
24
+ });
25
+ if (!response.ok) {
26
+ const errorBody = await response.text();
27
+ throw new Error(`SensorTower API error (${response.status}): ${errorBody}`);
28
+ }
29
+ return response.json();
30
+ }
31
+ async getApps(os, appIds, country) {
32
+ return this.request(`/v1/${os}/apps`, {
33
+ app_ids: appIds,
34
+ country
35
+ });
36
+ }
37
+ async getTopInAppPurchases(appIds, country) {
38
+ return this.request('/v1/ios/apps/top_in_app_purchases', {
39
+ app_ids: appIds,
40
+ country
41
+ });
42
+ }
43
+ async getSalesReportEstimates(os, options) {
44
+ return this.request(`/v1/${os}/sales_report_estimates`, {
45
+ app_ids: options.appIds,
46
+ publisher_ids: options.publisherIds,
47
+ unified_app_ids: options.unifiedAppIds,
48
+ unified_publisher_ids: options.unifiedPublisherIds,
49
+ categories: options.categories,
50
+ countries: options.countries,
51
+ date_granularity: options.dateGranularity,
52
+ start_date: options.startDate,
53
+ end_date: options.endDate,
54
+ data_model: options.dataModel
55
+ });
56
+ }
57
+ async getCompactSalesReport(os, options) {
58
+ return this.request(`/v1/${os}/compact_sales_report_estimates`, {
59
+ app_ids: options.appIds,
60
+ publisher_ids: options.publisherIds,
61
+ unified_app_ids: options.unifiedAppIds,
62
+ unified_publisher_ids: options.unifiedPublisherIds,
63
+ categories: options.categories,
64
+ countries: options.countries,
65
+ date_granularity: options.dateGranularity,
66
+ start_date: options.startDate,
67
+ end_date: options.endDate,
68
+ data_model: options.dataModel
69
+ });
70
+ }
71
+ async getActiveUsers(os, options) {
72
+ return this.request(`/v1/${os}/usage/active_users`, {
73
+ app_ids: options.appIds,
74
+ time_period: options.timePeriod,
75
+ start_date: options.startDate,
76
+ end_date: options.endDate,
77
+ countries: options.countries,
78
+ data_model: options.dataModel
79
+ });
80
+ }
81
+ async getCategoryHistory(os, options) {
82
+ return this.request(`/v1/${os}/category/category_history`, {
83
+ app_ids: options.appIds,
84
+ category: options.category,
85
+ chart_type_ids: options.chartTypeIds,
86
+ countries: options.countries,
87
+ start_date: options.startDate,
88
+ end_date: options.endDate,
89
+ is_hourly: options.isHourly?.toString()
90
+ });
91
+ }
92
+ async getCategoryRankingSummary(os, appId, country) {
93
+ return this.request(`/v1/${os}/category/category_ranking_summary`, {
94
+ app_id: appId,
95
+ country
96
+ });
97
+ }
98
+ async getNetworkAnalysis(os, options) {
99
+ return this.request(`/v1/${os}/ad_intel/network_analysis`, {
100
+ app_ids: options.appIds,
101
+ start_date: options.startDate,
102
+ end_date: options.endDate,
103
+ period: options.period,
104
+ networks: options.networks,
105
+ countries: options.countries
106
+ });
107
+ }
108
+ async getNetworkAnalysisRank(os, options) {
109
+ return this.request(`/v1/${os}/ad_intel/network_analysis/rank`, {
110
+ app_ids: options.appIds,
111
+ start_date: options.startDate,
112
+ end_date: options.endDate,
113
+ period: options.period,
114
+ networks: options.networks,
115
+ countries: options.countries
116
+ });
117
+ }
118
+ async getRetention(os, options) {
119
+ return this.request(`/v1/${os}/usage/retention`, {
120
+ app_ids: options.appIds,
121
+ date_granularity: options.dateGranularity,
122
+ start_date: options.startDate,
123
+ end_date: options.endDate,
124
+ country: options.country
125
+ });
126
+ }
127
+ async getDownloadsBySources(os, options) {
128
+ return this.request(`/v1/${os}/downloads_by_sources`, {
129
+ app_ids: options.appIds,
130
+ countries: options.countries,
131
+ date_granularity: options.dateGranularity,
132
+ start_date: options.startDate,
133
+ end_date: options.endDate
134
+ });
135
+ }
136
+ }
137
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { AppIdDiscoveryResult } from './types.js';
2
+ export declare function parseAppStoreUrl(url: string): AppIdDiscoveryResult | null;
3
+ export declare function extractAppIdFromText(text: string): AppIdDiscoveryResult[];
4
+ export declare function generateSearchQuery(appName: string, platform: 'ios' | 'android'): string;
5
+ export declare function parseSearchResultsForAppId(searchResults: string, platform: 'ios' | 'android'): AppIdDiscoveryResult | null;
6
+ export interface AppIdentifier {
7
+ type: 'app_id' | 'app_name' | 'store_url';
8
+ value: string;
9
+ platform?: 'ios' | 'android';
10
+ }
11
+ export declare function identifyAppInput(input: string): AppIdentifier;
12
+ export declare function createAppDiscoveryInstructions(appName: string): string;
13
+ //# sourceMappingURL=app-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-discovery.d.ts","sourceRoot":"","sources":["../src/app-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAElD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAsCzE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAczE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAMxF;AAED,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,KAAK,GAAG,SAAS,GAC1B,oBAAoB,GAAG,IAAI,CAwB7B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;CAC9B;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAkB7D;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAYtE"}
@@ -0,0 +1,107 @@
1
+ export function parseAppStoreUrl(url) {
2
+ const iosPattern = /apps\.apple\.com\/.*\/app\/.*\/id(\d+)/i;
3
+ const iosMatch = url.match(iosPattern);
4
+ if (iosMatch) {
5
+ return {
6
+ platform: 'ios',
7
+ app_id: iosMatch[1],
8
+ store_url: url,
9
+ source: 'url_parse'
10
+ };
11
+ }
12
+ const iosAltPattern = /itunes\.apple\.com\/.*\/app\/.*\/id(\d+)/i;
13
+ const iosAltMatch = url.match(iosAltPattern);
14
+ if (iosAltMatch) {
15
+ return {
16
+ platform: 'ios',
17
+ app_id: iosAltMatch[1],
18
+ store_url: url,
19
+ source: 'url_parse'
20
+ };
21
+ }
22
+ const androidPattern = /play\.google\.com\/store\/apps\/details\?id=([a-zA-Z0-9._]+)/i;
23
+ const androidMatch = url.match(androidPattern);
24
+ if (androidMatch) {
25
+ return {
26
+ platform: 'android',
27
+ app_id: androidMatch[1],
28
+ store_url: url,
29
+ source: 'url_parse'
30
+ };
31
+ }
32
+ return null;
33
+ }
34
+ export function extractAppIdFromText(text) {
35
+ const results = [];
36
+ const urlPattern = /(https?:\/\/[^\s]+)/gi;
37
+ const urls = text.match(urlPattern) || [];
38
+ for (const url of urls) {
39
+ const result = parseAppStoreUrl(url);
40
+ if (result) {
41
+ results.push(result);
42
+ }
43
+ }
44
+ return results;
45
+ }
46
+ export function generateSearchQuery(appName, platform) {
47
+ if (platform === 'ios') {
48
+ return `${appName} site:apps.apple.com app store`;
49
+ }
50
+ else {
51
+ return `${appName} site:play.google.com google play store`;
52
+ }
53
+ }
54
+ export function parseSearchResultsForAppId(searchResults, platform) {
55
+ if (platform === 'ios') {
56
+ const pattern = /apps\.apple\.com\/[a-z]{2}\/app\/[^\/]+\/id(\d+)/i;
57
+ const match = searchResults.match(pattern);
58
+ if (match) {
59
+ return {
60
+ platform: 'ios',
61
+ app_id: match[1],
62
+ source: 'search'
63
+ };
64
+ }
65
+ }
66
+ else {
67
+ const pattern = /play\.google\.com\/store\/apps\/details\?id=([a-zA-Z0-9._]+)/i;
68
+ const match = searchResults.match(pattern);
69
+ if (match) {
70
+ return {
71
+ platform: 'android',
72
+ app_id: match[1],
73
+ source: 'search'
74
+ };
75
+ }
76
+ }
77
+ return null;
78
+ }
79
+ export function identifyAppInput(input) {
80
+ if (input.includes('apps.apple.com') || input.includes('itunes.apple.com')) {
81
+ return { type: 'store_url', value: input, platform: 'ios' };
82
+ }
83
+ if (input.includes('play.google.com')) {
84
+ return { type: 'store_url', value: input, platform: 'android' };
85
+ }
86
+ if (/^\d+$/.test(input)) {
87
+ return { type: 'app_id', value: input, platform: 'ios' };
88
+ }
89
+ if (/^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$/i.test(input)) {
90
+ return { type: 'app_id', value: input, platform: 'android' };
91
+ }
92
+ return { type: 'app_name', value: input };
93
+ }
94
+ export function createAppDiscoveryInstructions(appName) {
95
+ return `To find the App ID for "${appName}", please:
96
+
97
+ 1. **For iOS apps**: Search for "${appName} site:apps.apple.com" and extract the numeric ID from the URL
98
+ - URL format: https://apps.apple.com/.../id[NUMERIC_ID]
99
+ - Example: https://apps.apple.com/us/app/facebook/id284882215 → App ID: 284882215
100
+
101
+ 2. **For Android apps**: Search for "${appName} site:play.google.com" and extract the package name
102
+ - URL format: https://play.google.com/store/apps/details?id=[PACKAGE_NAME]
103
+ - Example: https://play.google.com/store/apps/details?id=com.facebook.katana → App ID: com.facebook.katana
104
+
105
+ Once you have the App ID, you can use it with the SensorTower API tools.`;
106
+ }
107
+ //# sourceMappingURL=app-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-discovery.js","sourceRoot":"","sources":["../src/app-discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,512 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
+ import { SensorTowerClient } from './api-client.js';
6
+ import { parseAppStoreUrl, identifyAppInput, createAppDiscoveryInstructions, generateSearchQuery, } from './app-discovery.js';
7
+ import { AD_NETWORKS, IOS_CATEGORIES, CHART_TYPES } from './types.js';
8
+ const SERVER_NAME = 'sensor-tower-mcp';
9
+ const SERVER_VERSION = '1.0.0';
10
+ let client = null;
11
+ function getClient() {
12
+ if (!client) {
13
+ const authToken = process.env.SENSOR_TOWER_AUTH_TOKEN;
14
+ if (!authToken) {
15
+ throw new Error('SENSOR_TOWER_AUTH_TOKEN environment variable is required. ' +
16
+ 'Please set it in your MCP server configuration.');
17
+ }
18
+ client = new SensorTowerClient({ authToken });
19
+ }
20
+ return client;
21
+ }
22
+ const server = new Server({ name: SERVER_NAME, version: SERVER_VERSION }, { capabilities: { tools: {}, prompts: {} } });
23
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
24
+ return {
25
+ tools: [
26
+ {
27
+ name: 'discover_app_id',
28
+ description: 'Parse App Store or Google Play URL to extract app ID, or provide instructions for finding app ID by name',
29
+ inputSchema: {
30
+ type: 'object',
31
+ properties: {
32
+ input: {
33
+ type: 'string',
34
+ description: 'App Store URL, Google Play URL, or app name to discover'
35
+ },
36
+ platform: {
37
+ type: 'string',
38
+ enum: ['ios', 'android'],
39
+ description: 'Target platform (required if input is app name)'
40
+ }
41
+ },
42
+ required: ['input']
43
+ }
44
+ },
45
+ {
46
+ name: 'get_app_info',
47
+ description: 'Get app metadata including name, publisher, categories, ratings, and more',
48
+ inputSchema: {
49
+ type: 'object',
50
+ properties: {
51
+ os: { type: 'string', enum: ['ios', 'android'], description: 'Operating system' },
52
+ app_ids: { type: 'array', items: { type: 'string' }, description: 'App IDs (max 100)' },
53
+ country: { type: 'string', description: 'Country code (default: US)' }
54
+ },
55
+ required: ['os', 'app_ids']
56
+ }
57
+ },
58
+ {
59
+ name: 'get_top_in_app_purchases',
60
+ description: 'Get top in-app purchases for iOS apps',
61
+ inputSchema: {
62
+ type: 'object',
63
+ properties: {
64
+ app_ids: { type: 'array', items: { type: 'string' }, description: 'iOS App IDs' },
65
+ country: { type: 'string', description: 'Country code' }
66
+ },
67
+ required: ['app_ids']
68
+ }
69
+ },
70
+ {
71
+ name: 'get_sales_report',
72
+ description: 'Get download and revenue estimates for apps by country and date',
73
+ inputSchema: {
74
+ type: 'object',
75
+ properties: {
76
+ os: { type: 'string', enum: ['ios', 'android', 'unified'], description: 'Operating system' },
77
+ app_ids: { type: 'array', items: { type: 'string' }, description: 'App IDs' },
78
+ countries: { type: 'array', items: { type: 'string' }, description: 'Country codes (WW for worldwide)' },
79
+ date_granularity: { type: 'string', enum: ['daily', 'weekly', 'monthly', 'quarterly'], description: 'Date granularity' },
80
+ start_date: { type: 'string', description: 'Start date (YYYY-MM-DD)' },
81
+ end_date: { type: 'string', description: 'End date (YYYY-MM-DD)' }
82
+ },
83
+ required: ['os', 'app_ids', 'date_granularity', 'start_date', 'end_date']
84
+ }
85
+ },
86
+ {
87
+ name: 'get_active_users',
88
+ description: 'Get active user estimates (DAU/WAU/MAU) for apps',
89
+ inputSchema: {
90
+ type: 'object',
91
+ properties: {
92
+ os: { type: 'string', enum: ['ios', 'android', 'unified'], description: 'Operating system' },
93
+ app_ids: { type: 'array', items: { type: 'string' }, description: 'App IDs (max 500)' },
94
+ time_period: { type: 'string', enum: ['day', 'week', 'month'], description: 'Time period: day=DAU, week=WAU, month=MAU' },
95
+ start_date: { type: 'string', description: 'Start date (YYYY-MM-DD)' },
96
+ end_date: { type: 'string', description: 'End date (YYYY-MM-DD)' },
97
+ countries: { type: 'array', items: { type: 'string' }, description: 'Country codes' }
98
+ },
99
+ required: ['os', 'app_ids', 'time_period', 'start_date', 'end_date']
100
+ }
101
+ },
102
+ {
103
+ name: 'get_category_ranking_history',
104
+ description: 'Get historical category ranking for apps',
105
+ inputSchema: {
106
+ type: 'object',
107
+ properties: {
108
+ os: { type: 'string', enum: ['ios', 'android'], description: 'Operating system' },
109
+ app_ids: { type: 'array', items: { type: 'string' }, description: 'App IDs' },
110
+ category: { type: 'string', description: 'Category ID (e.g., 6005 for Social Networking)' },
111
+ chart_type_ids: { type: 'array', items: { type: 'string' }, description: 'Chart type IDs: 0=free, 1=paid, 2=grossing' },
112
+ countries: { type: 'array', items: { type: 'string' }, description: 'Country codes' },
113
+ start_date: { type: 'string', description: 'Start date (YYYY-MM-DD)' },
114
+ end_date: { type: 'string', description: 'End date (YYYY-MM-DD)' }
115
+ },
116
+ required: ['os', 'app_ids', 'category', 'chart_type_ids', 'start_date', 'end_date']
117
+ }
118
+ },
119
+ {
120
+ name: 'get_category_ranking_summary',
121
+ description: 'Get current category ranking summary for an app',
122
+ inputSchema: {
123
+ type: 'object',
124
+ properties: {
125
+ os: { type: 'string', enum: ['ios', 'android'], description: 'Operating system' },
126
+ app_id: { type: 'string', description: 'Single App ID' },
127
+ country: { type: 'string', description: 'Country code' }
128
+ },
129
+ required: ['os', 'app_id']
130
+ }
131
+ },
132
+ {
133
+ name: 'get_ad_network_analysis',
134
+ description: 'Get advertising share of voice (SOV) time series for apps',
135
+ inputSchema: {
136
+ type: 'object',
137
+ properties: {
138
+ os: { type: 'string', enum: ['ios', 'android', 'unified'], description: 'Operating system' },
139
+ app_ids: { type: 'array', items: { type: 'string' }, description: 'App IDs' },
140
+ start_date: { type: 'string', description: 'Start date (YYYY-MM-DD), min: 2018-01-01' },
141
+ end_date: { type: 'string', description: 'End date (YYYY-MM-DD)' },
142
+ period: { type: 'string', enum: ['day', 'week', 'month'], description: 'Time period' },
143
+ networks: { type: 'array', items: { type: 'string' }, description: 'Ad networks (e.g., Facebook, Admob, Unity)' },
144
+ countries: { type: 'array', items: { type: 'string' }, description: 'Country codes' }
145
+ },
146
+ required: ['os', 'app_ids', 'start_date', 'end_date', 'period']
147
+ }
148
+ },
149
+ {
150
+ name: 'get_ad_network_rank',
151
+ description: 'Get advertising rank for apps across networks and countries',
152
+ inputSchema: {
153
+ type: 'object',
154
+ properties: {
155
+ os: { type: 'string', enum: ['ios', 'android', 'unified'], description: 'Operating system' },
156
+ app_ids: { type: 'array', items: { type: 'string' }, description: 'App IDs' },
157
+ start_date: { type: 'string', description: 'Start date (YYYY-MM-DD)' },
158
+ end_date: { type: 'string', description: 'End date (YYYY-MM-DD)' },
159
+ period: { type: 'string', enum: ['day', 'week'], description: 'Time period (day or week only)' },
160
+ networks: { type: 'array', items: { type: 'string' }, description: 'Ad networks' },
161
+ countries: { type: 'array', items: { type: 'string' }, description: 'Country codes' }
162
+ },
163
+ required: ['os', 'app_ids', 'start_date', 'end_date', 'period']
164
+ }
165
+ },
166
+ {
167
+ name: 'get_retention',
168
+ description: 'Get app retention data (Day 1 to Day 90)',
169
+ inputSchema: {
170
+ type: 'object',
171
+ properties: {
172
+ os: { type: 'string', enum: ['ios', 'android'], description: 'Operating system' },
173
+ app_ids: { type: 'array', items: { type: 'string' }, description: 'App IDs' },
174
+ date_granularity: { type: 'string', enum: ['all_time', 'quarterly'], description: 'Date granularity' },
175
+ start_date: { type: 'string', description: 'Start date (YYYY-MM-DD)' },
176
+ end_date: { type: 'string', description: 'End date (YYYY-MM-DD), ignored for all_time' },
177
+ country: { type: 'string', description: 'Country code (default: WW)' }
178
+ },
179
+ required: ['os', 'app_ids', 'date_granularity', 'start_date']
180
+ }
181
+ },
182
+ {
183
+ name: 'get_downloads_by_source',
184
+ description: 'Get downloads breakdown by source (organic, paid, browser)',
185
+ inputSchema: {
186
+ type: 'object',
187
+ properties: {
188
+ os: { type: 'string', enum: ['ios', 'android', 'unified'], description: 'Operating system' },
189
+ app_ids: { type: 'array', items: { type: 'string' }, description: 'Unified App IDs' },
190
+ countries: { type: 'array', items: { type: 'string' }, description: 'Country codes (WW for worldwide)' },
191
+ date_granularity: { type: 'string', enum: ['daily', 'monthly'], description: 'Date granularity' },
192
+ start_date: { type: 'string', description: 'Start date (YYYY-MM-DD)' },
193
+ end_date: { type: 'string', description: 'End date (YYYY-MM-DD)' }
194
+ },
195
+ required: ['os', 'app_ids', 'countries', 'start_date', 'end_date']
196
+ }
197
+ },
198
+ {
199
+ name: 'list_categories',
200
+ description: 'List available iOS category IDs',
201
+ inputSchema: {
202
+ type: 'object',
203
+ properties: {}
204
+ }
205
+ },
206
+ {
207
+ name: 'list_ad_networks',
208
+ description: 'List available ad networks for network analysis',
209
+ inputSchema: {
210
+ type: 'object',
211
+ properties: {}
212
+ }
213
+ }
214
+ ]
215
+ };
216
+ });
217
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
218
+ const { name, arguments: args } = request.params;
219
+ try {
220
+ switch (name) {
221
+ case 'discover_app_id': {
222
+ const input = args?.input;
223
+ const platform = args?.platform;
224
+ const identified = identifyAppInput(input);
225
+ if (identified.type === 'store_url') {
226
+ const result = parseAppStoreUrl(input);
227
+ if (result) {
228
+ return {
229
+ content: [{
230
+ type: 'text',
231
+ text: JSON.stringify({
232
+ success: true,
233
+ platform: result.platform,
234
+ app_id: result.app_id,
235
+ source: 'url_parse'
236
+ }, null, 2)
237
+ }]
238
+ };
239
+ }
240
+ }
241
+ if (identified.type === 'app_id') {
242
+ return {
243
+ content: [{
244
+ type: 'text',
245
+ text: JSON.stringify({
246
+ success: true,
247
+ platform: identified.platform,
248
+ app_id: identified.value,
249
+ source: 'direct_id'
250
+ }, null, 2)
251
+ }]
252
+ };
253
+ }
254
+ const targetPlatform = platform || 'ios';
255
+ const searchQuery = generateSearchQuery(input, targetPlatform);
256
+ const instructions = createAppDiscoveryInstructions(input);
257
+ return {
258
+ content: [{
259
+ type: 'text',
260
+ text: JSON.stringify({
261
+ success: false,
262
+ app_name: input,
263
+ platform: targetPlatform,
264
+ search_query: searchQuery,
265
+ instructions: instructions,
266
+ note: 'Use web search with the provided query to find the app store URL, then extract the App ID'
267
+ }, null, 2)
268
+ }]
269
+ };
270
+ }
271
+ case 'get_app_info': {
272
+ const apiClient = getClient();
273
+ const result = await apiClient.getApps(args?.os, args?.app_ids, args?.country);
274
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
275
+ }
276
+ case 'get_top_in_app_purchases': {
277
+ const apiClient = getClient();
278
+ const result = await apiClient.getTopInAppPurchases(args?.app_ids, args?.country);
279
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
280
+ }
281
+ case 'get_sales_report': {
282
+ const apiClient = getClient();
283
+ const result = await apiClient.getSalesReportEstimates(args?.os, {
284
+ appIds: args?.app_ids,
285
+ countries: args?.countries,
286
+ dateGranularity: args?.date_granularity,
287
+ startDate: args?.start_date,
288
+ endDate: args?.end_date
289
+ });
290
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
291
+ }
292
+ case 'get_active_users': {
293
+ const apiClient = getClient();
294
+ const result = await apiClient.getActiveUsers(args?.os, {
295
+ appIds: args?.app_ids,
296
+ timePeriod: args?.time_period,
297
+ startDate: args?.start_date,
298
+ endDate: args?.end_date,
299
+ countries: args?.countries
300
+ });
301
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
302
+ }
303
+ case 'get_category_ranking_history': {
304
+ const apiClient = getClient();
305
+ const result = await apiClient.getCategoryHistory(args?.os, {
306
+ appIds: args?.app_ids,
307
+ category: args?.category,
308
+ chartTypeIds: args?.chart_type_ids,
309
+ countries: args?.countries,
310
+ startDate: args?.start_date,
311
+ endDate: args?.end_date
312
+ });
313
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
314
+ }
315
+ case 'get_category_ranking_summary': {
316
+ const apiClient = getClient();
317
+ const result = await apiClient.getCategoryRankingSummary(args?.os, args?.app_id, args?.country);
318
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
319
+ }
320
+ case 'get_ad_network_analysis': {
321
+ const apiClient = getClient();
322
+ const result = await apiClient.getNetworkAnalysis(args?.os, {
323
+ appIds: args?.app_ids,
324
+ startDate: args?.start_date,
325
+ endDate: args?.end_date,
326
+ period: args?.period,
327
+ networks: args?.networks,
328
+ countries: args?.countries
329
+ });
330
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
331
+ }
332
+ case 'get_ad_network_rank': {
333
+ const apiClient = getClient();
334
+ const result = await apiClient.getNetworkAnalysisRank(args?.os, {
335
+ appIds: args?.app_ids,
336
+ startDate: args?.start_date,
337
+ endDate: args?.end_date,
338
+ period: args?.period,
339
+ networks: args?.networks,
340
+ countries: args?.countries
341
+ });
342
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
343
+ }
344
+ case 'get_retention': {
345
+ const apiClient = getClient();
346
+ const result = await apiClient.getRetention(args?.os, {
347
+ appIds: args?.app_ids,
348
+ dateGranularity: args?.date_granularity,
349
+ startDate: args?.start_date,
350
+ endDate: args?.end_date,
351
+ country: args?.country
352
+ });
353
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
354
+ }
355
+ case 'get_downloads_by_source': {
356
+ const apiClient = getClient();
357
+ const result = await apiClient.getDownloadsBySources(args?.os, {
358
+ appIds: args?.app_ids,
359
+ countries: args?.countries,
360
+ dateGranularity: args?.date_granularity,
361
+ startDate: args?.start_date,
362
+ endDate: args?.end_date
363
+ });
364
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
365
+ }
366
+ case 'list_categories': {
367
+ return {
368
+ content: [{
369
+ type: 'text',
370
+ text: JSON.stringify({
371
+ ios_categories: IOS_CATEGORIES,
372
+ chart_types: CHART_TYPES,
373
+ note: 'For full category list, see: https://app.sensortower.com/api/docs/static/category_ids.json'
374
+ }, null, 2)
375
+ }]
376
+ };
377
+ }
378
+ case 'list_ad_networks': {
379
+ return {
380
+ content: [{
381
+ type: 'text',
382
+ text: JSON.stringify({
383
+ networks: AD_NETWORKS,
384
+ note: 'Use these network names in the get_ad_network_analysis and get_ad_network_rank tools'
385
+ }, null, 2)
386
+ }]
387
+ };
388
+ }
389
+ default:
390
+ throw new Error(`Unknown tool: ${name}`);
391
+ }
392
+ }
393
+ catch (error) {
394
+ const errorMessage = error instanceof Error ? error.message : String(error);
395
+ return {
396
+ content: [{ type: 'text', text: `Error: ${errorMessage}` }],
397
+ isError: true
398
+ };
399
+ }
400
+ });
401
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
402
+ return {
403
+ prompts: [
404
+ {
405
+ name: 'analyze_app',
406
+ description: 'Comprehensive app analysis workflow - finds app ID and retrieves key metrics',
407
+ arguments: [
408
+ { name: 'app_name_or_url', description: 'App name, App Store URL, or Google Play URL', required: true },
409
+ { name: 'platform', description: 'ios or android (required if providing app name)', required: false }
410
+ ]
411
+ },
412
+ {
413
+ name: 'compare_apps',
414
+ description: 'Compare multiple apps on key metrics',
415
+ arguments: [
416
+ { name: 'apps', description: 'Comma-separated list of app names or IDs', required: true },
417
+ { name: 'platform', description: 'ios or android', required: true }
418
+ ]
419
+ }
420
+ ]
421
+ };
422
+ });
423
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
424
+ const { name, arguments: args } = request.params;
425
+ switch (name) {
426
+ case 'analyze_app': {
427
+ const appInput = args?.app_name_or_url || '';
428
+ const platform = args?.platform || 'ios';
429
+ return {
430
+ messages: [
431
+ {
432
+ role: 'user',
433
+ content: {
434
+ type: 'text',
435
+ text: `Please analyze the app: "${appInput}" on ${platform} platform.
436
+
437
+ ## Workflow:
438
+
439
+ 1. **App ID Discovery**:
440
+ - If a URL is provided, extract the App ID directly
441
+ - If only a name is provided, search for the official store page:
442
+ • iOS: Search "${appInput} site:apps.apple.com" → extract ID from /id[NUMBER]
443
+ • Android: Search "${appInput} site:play.google.com" → extract package name from ?id=[PACKAGE]
444
+
445
+ 2. **Once App ID is found, retrieve**:
446
+ - Basic app info (get_app_info)
447
+ - Current category rankings (get_category_ranking_summary)
448
+ - Recent downloads and revenue (get_sales_report) - last 30 days
449
+ - Active users if available (get_active_users) - last 30 days
450
+
451
+ 3. **Provide a summary** including:
452
+ - App name, publisher, category
453
+ - Current rankings
454
+ - Download/revenue trends
455
+ - User engagement metrics
456
+
457
+ If App ID cannot be found, clearly note this limitation and proceed with available information.`
458
+ }
459
+ }
460
+ ]
461
+ };
462
+ }
463
+ case 'compare_apps': {
464
+ const apps = args?.apps || '';
465
+ const platform = args?.platform || 'ios';
466
+ return {
467
+ messages: [
468
+ {
469
+ role: 'user',
470
+ content: {
471
+ type: 'text',
472
+ text: `Please compare these apps: ${apps} on ${platform} platform.
473
+
474
+ ## Workflow:
475
+
476
+ 1. **For each app**, discover the App ID (from URL or search)
477
+
478
+ 2. **Retrieve comparative metrics**:
479
+ - Basic app info for all apps
480
+ - Downloads and revenue (last 30 days)
481
+ - Category rankings
482
+ - Active users if available
483
+
484
+ 3. **Create a comparison table** showing:
485
+ - App name and publisher
486
+ - Category and rankings
487
+ - Downloads and revenue
488
+ - User engagement
489
+
490
+ 4. **Provide insights** on:
491
+ - Market position of each app
492
+ - Relative strengths and weaknesses
493
+ - Growth trends`
494
+ }
495
+ }
496
+ ]
497
+ };
498
+ }
499
+ default:
500
+ throw new Error(`Unknown prompt: ${name}`);
501
+ }
502
+ });
503
+ async function main() {
504
+ const transport = new StdioServerTransport();
505
+ await server.connect(transport);
506
+ console.error(`${SERVER_NAME} v${SERVER_VERSION} running on stdio`);
507
+ }
508
+ main().catch((error) => {
509
+ console.error('Fatal error:', error);
510
+ process.exit(1);
511
+ });
512
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ export interface SensorTowerConfig {
2
+ authToken: string;
3
+ baseUrl?: string;
4
+ }
5
+ export type OsType = 'ios' | 'android' | 'unified';
6
+ export type TimePeriod = 'day' | 'week' | 'month';
7
+ export type DateGranularity = 'daily' | 'weekly' | 'monthly' | 'quarterly' | 'all_time';
8
+ export type AdIntelPeriod = 'day' | 'week' | 'month';
9
+ export interface AppInfo {
10
+ app_id: string | number;
11
+ name: string;
12
+ publisher_name: string;
13
+ os: OsType;
14
+ unified_app_id?: string;
15
+ bundle_id?: string;
16
+ categories?: number[];
17
+ icon_url?: string;
18
+ rating?: number;
19
+ price?: number;
20
+ }
21
+ export interface ActiveUsersData {
22
+ app_id: string | number;
23
+ country: string;
24
+ date: string;
25
+ ipad_users?: number;
26
+ iphone_users?: number;
27
+ users?: number;
28
+ }
29
+ export interface SalesReportData {
30
+ app_id: string | number;
31
+ country: string;
32
+ date: string;
33
+ downloads?: number;
34
+ revenue?: number;
35
+ }
36
+ export interface CategoryRankingData {
37
+ app_id: string | number;
38
+ country: string;
39
+ category: string;
40
+ chart_type: string;
41
+ rank: number;
42
+ date: string;
43
+ }
44
+ export interface RetentionData {
45
+ app_id: string | number;
46
+ country: string;
47
+ date_granularity: string;
48
+ date: string;
49
+ corrected_retention: number[];
50
+ confidence?: number;
51
+ }
52
+ export interface NetworkAnalysisData {
53
+ app_id: string;
54
+ country: string;
55
+ network: string;
56
+ date: string;
57
+ sov: number;
58
+ }
59
+ export interface DownloadsBySourceData {
60
+ app_id: string;
61
+ breakdown: {
62
+ date: string;
63
+ organic_abs: number;
64
+ paid_abs: number;
65
+ browser_abs: number;
66
+ organic_frac: number;
67
+ paid_frac: number;
68
+ browser_frac: number;
69
+ }[];
70
+ }
71
+ export interface AppIdDiscoveryResult {
72
+ platform: 'ios' | 'android';
73
+ app_id: string;
74
+ app_name?: string;
75
+ store_url?: string;
76
+ source: 'url_parse' | 'search';
77
+ }
78
+ export declare const AD_NETWORKS: readonly ["Adcolony", "Admob", "Applovin", "BidMachine", "Chartboost", "Digital Turbine", "Facebook", "InMobi", "Instagram", "Line", "Meta Audience Network", "Mintegral", "Moloco", "Mopub", "Pangle", "Pinterest", "Smaato", "Snapchat", "Supersonic", "Tapjoy", "TikTok", "Twitter", "Unity", "Verve", "Vungle", "Youtube"];
79
+ export declare const IOS_CATEGORIES: Record<string, string>;
80
+ export declare const CHART_TYPES: Record<string, string>;
81
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,35 @@
1
+ export const AD_NETWORKS = [
2
+ 'Adcolony', 'Admob', 'Applovin', 'BidMachine', 'Chartboost',
3
+ 'Digital Turbine', 'Facebook', 'InMobi', 'Instagram', 'Line',
4
+ 'Meta Audience Network', 'Mintegral', 'Moloco', 'Mopub', 'Pangle',
5
+ 'Pinterest', 'Smaato', 'Snapchat', 'Supersonic', 'Tapjoy',
6
+ 'TikTok', 'Twitter', 'Unity', 'Verve', 'Vungle', 'Youtube'
7
+ ];
8
+ export const IOS_CATEGORIES = {
9
+ 'social_networking': '6005',
10
+ 'games': '6014',
11
+ 'entertainment': '6016',
12
+ 'photo_video': '6008',
13
+ 'music': '6011',
14
+ 'shopping': '6024',
15
+ 'finance': '6015',
16
+ 'health_fitness': '6013',
17
+ 'productivity': '6007',
18
+ 'news': '6009',
19
+ 'education': '6017',
20
+ 'lifestyle': '6012',
21
+ 'utilities': '6002',
22
+ 'travel': '6003',
23
+ 'sports': '6004',
24
+ 'food_drink': '6023',
25
+ 'business': '6000',
26
+ 'weather': '6001',
27
+ 'reference': '6006',
28
+ 'navigation': '6010'
29
+ };
30
+ export const CHART_TYPES = {
31
+ 'free': '0',
32
+ 'paid': '1',
33
+ 'grossing': '2'
34
+ };
35
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAuFA,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY;IAC3D,iBAAiB,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM;IAC5D,uBAAuB,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ;IACjE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ;IACzD,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS;CAClD,CAAC;AAEX,MAAM,CAAC,MAAM,cAAc,GAA2B;IACpD,mBAAmB,EAAE,MAAM;IAC3B,OAAO,EAAE,MAAM;IACf,eAAe,EAAE,MAAM;IACvB,aAAa,EAAE,MAAM;IACrB,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,MAAM;IACjB,gBAAgB,EAAE,MAAM;IACxB,cAAc,EAAE,MAAM;IACtB,MAAM,EAAE,MAAM;IACd,WAAW,EAAE,MAAM;IACnB,WAAW,EAAE,MAAM;IACnB,WAAW,EAAE,MAAM;IACnB,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,MAAM;IACpB,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,MAAM;IACjB,WAAW,EAAE,MAAM;IACnB,YAAY,EAAE,MAAM;CACrB,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAA2B;IACjD,MAAM,EAAE,GAAG;IACX,MAAM,EAAE,GAAG;IACX,UAAU,EAAE,GAAG;CAChB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "sensor-tower-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for SensorTower API - App Intelligence, Downloads, Revenue, Active Users, and more",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "sensor-tower-mcp": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/index.js",
13
+ "dev": "tsc --watch",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "keywords": [
17
+ "mcp",
18
+ "sensortower",
19
+ "app-intelligence",
20
+ "mobile-analytics",
21
+ "app-store",
22
+ "google-play"
23
+ ],
24
+ "author": "",
25
+ "license": "MIT",
26
+ "dependencies": {
27
+ "@modelcontextprotocol/sdk": "^1.0.0"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^20.10.0",
31
+ "typescript": "^5.3.0"
32
+ },
33
+ "engines": {
34
+ "node": ">=18.0.0"
35
+ },
36
+ "files": [
37
+ "dist"
38
+ ]
39
+ }