get_interaction_network
Build and analyze protein interaction networks for multiple proteins using the STRING database to identify functional or physical relationships between proteins.
Instructions
Build and analyze protein interaction network for multiple proteins
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| protein_ids | Yes | List of protein identifiers | |
| species | No | Species name or NCBI taxonomy ID (default: 9606 for human) | |
| network_type | No | Type of network to build (default: functional) | |
| add_nodes | No | Number of additional interacting proteins to add (default: 0) | |
| required_score | No | Minimum interaction confidence score (0-1000, default: 400) |
Implementation Reference
- src/index.ts:519-590 (handler)The primary handler function that implements the logic for the 'get_interaction_network' tool. It validates arguments, queries the STRING API for network interactions and node data, parses the TSV responses, computes network statistics, and returns a structured JSON response with nodes and edges.private async handleGetInteractionNetwork(args: any) { if (!isValidNetworkArgs(args)) { throw new McpError(ErrorCode.InvalidParams, 'Invalid network arguments'); } try { const species = args.species || '9606'; const addNodes = args.add_nodes || 0; const requiredScore = args.required_score || 400; // Get network data const networkResponse = await this.apiClient.get('/tsv/network', { params: { identifiers: args.protein_ids.join('%0d'), species: species, add_white_nodes: addNodes, required_score: requiredScore, }, }); const interactions = this.parseTsvData<ProteinInteraction>(networkResponse.data); // Get node annotations const nodeResponse = await this.apiClient.get('/tsv/get_string_ids', { params: { identifiers: args.protein_ids.join('%0d'), species: species, }, }); const nodes = this.parseTsvData<NetworkNode>(nodeResponse.data); return { content: [ { type: 'text', text: JSON.stringify({ query_proteins: args.protein_ids, species: species, network_stats: { total_nodes: nodes.length, total_edges: interactions.length, average_degree: interactions.length > 0 ? (interactions.length * 2) / nodes.length : 0, }, nodes: nodes.map(node => ({ protein_name: node.preferredName, string_id: node.stringId, annotation: node.annotation, protein_size: node.protein_size, })), edges: interactions.map(int => ({ protein_a: int.preferredName_A, protein_b: int.preferredName_B, confidence_score: int.score, evidence_types: this.getEvidenceTypes(int), })) }, null, 2), }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error building interaction network: ${error instanceof Error ? error.message : 'Unknown error'}`, }, ], isError: true, }; } }
- src/index.ts:322-336 (schema)The input schema and metadata definition for the 'get_interaction_network' tool, registered in the ListTools response.{ name: 'get_interaction_network', description: 'Build and analyze protein interaction network for multiple proteins', inputSchema: { type: 'object', properties: { protein_ids: { type: 'array', items: { type: 'string' }, description: 'List of protein identifiers' }, species: { type: 'string', description: 'Species name or NCBI taxonomy ID (default: 9606 for human)' }, network_type: { type: 'string', enum: ['functional', 'physical'], description: 'Type of network to build (default: functional)' }, add_nodes: { type: 'number', description: 'Number of additional interacting proteins to add (default: 0)', minimum: 0, maximum: 100 }, required_score: { type: 'number', description: 'Minimum interaction confidence score (0-1000, default: 400)', minimum: 0, maximum: 1000 }, }, required: ['protein_ids'], }, },
- src/index.ts:397-398 (registration)Registration in the CallToolRequestHandler switch statement that dispatches tool calls to the appropriate handler.case 'get_interaction_network': return this.handleGetInteractionNetwork(args);
- src/index.ts:83-96 (helper)Helper function for validating the input arguments specific to the network tool.const isValidNetworkArgs = ( args: any ): args is { protein_ids: string[]; species?: string; network_type?: string; add_nodes?: number; required_score?: number } => { return ( typeof args === 'object' && args !== null && Array.isArray(args.protein_ids) && args.protein_ids.length > 0 && args.protein_ids.every((id: any) => typeof id === 'string') && (args.species === undefined || typeof args.species === 'string') && (args.network_type === undefined || ['functional', 'physical'].includes(args.network_type)) && (args.add_nodes === undefined || (typeof args.add_nodes === 'number' && args.add_nodes >= 0 && args.add_nodes <= 100)) && (args.required_score === undefined || (typeof args.required_score === 'number' && args.required_score >= 0 && args.required_score <= 1000)) );
- src/index.ts:417-444 (helper)Utility function to parse TSV data from STRING API responses into typed objects, heavily used in the handler.private parseTsvData<T>(tsvData: string): T[] { const lines = tsvData.trim().split('\n'); if (lines.length < 2) return []; const headers = lines[0].split('\t'); const results: T[] = []; for (let i = 1; i < lines.length; i++) { const values = lines[i].split('\t'); const obj: any = {}; headers.forEach((header, index) => { const value = values[index] || ''; // Convert numeric fields if (['score', 'nscore', 'fscore', 'pscore', 'ascore', 'escore', 'dscore', 'tscore', 'ncbiTaxonId', 'protein_size', 'number_of_genes', 'number_of_genes_in_background', 'pvalue', 'pvalue_fdr'].includes(header)) { obj[header] = parseFloat(value) || 0; } else { obj[header] = value; } }); results.push(obj as T); } return results; }