vk_friends_search
Search VK friends by name or other criteria. Retrieve matching profiles with customizable fields, limits, and pagination.
Instructions
Returns a list of friends matching the search criteria.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | No | User ID. | |
| q | No | Search query string (e.g., 'Vasya Babich'). | |
| fields | No | Profile fields to return. Sample values: 'nickname', 'screen_name', 'sex', 'bdate' (birthdate), 'city', 'country', 'timezone', 'photo', 'photo_medium', 'photo_big', 'has_mobile', 'rate', 'contacts', 'education', 'online', | |
| name_case | No | Case for declension of user name and surname: 'nom' - nominative (default), 'gen' - genitive , 'dat' - dative, 'acc' - accusative , 'ins' - instrumental , 'abl' - prepositional | |
| offset | No | Offset needed to return a specific subset of friends. | |
| count | No | Number of friends to return. |
Implementation Reference
- src/tool-registry.js:19-24 (registration)buildTools maps each VK API method to an MCP tool. The tool name is derived from the method name via getToolName(), which converts 'friends.search' -> 'vk_friends_search'.
export function buildTools(methods) { return methods.map(method => ({ name: getToolName(method.name), description: cleanDescription(method.description, method.name), inputSchema: buildInputSchema(method.parameters), })); - src/tool-registry.js:3-8 (registration)getToolName converts VK API method names like 'friends.search' into MCP tool names like 'vk_friends_search' by replacing dots with underscores and lowercasing.
function getToolName(methodName) { return `vk_${methodName .replace(/\./g, '_') .replace(/([a-z0-9])([A-Z])/g, '$1_$2') .toLowerCase()}`; } - src/profiles.js:187-187 (registration)The 'friends.search' VK API method is included in the 'search' profile, which will be registered as tool 'vk_friends_search'.
'friends.search', - src/tool-registry.js:27-72 (handler)buildHandler creates the generic handler that dispatches tool calls. When 'vk_friends_search' is called, it looks up the corresponding VK method name 'friends.search' and calls vkClient.call('friends.search', args).
export function buildHandler(methods, vkClient) { const methodMap = new Map(); for (const method of methods) { methodMap.set(getToolName(method.name), method.name); } return async function handler(params) { const { name, arguments: args } = params; if (!methodMap.has(name)) { return { content: [ { type: 'text', text: JSON.stringify({ error: `Unknown tool: ${name}` }, null, 2), }, ], isError: true, }; } const vkMethod = methodMap.get(name); try { const result = await vkClient.call(vkMethod, args || {}); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } catch (error) { return { content: [ { type: 'text', text: JSON.stringify({ error: error.message }, null, 2), }, ], isError: true, }; } }; - src/vk-client.js:8-68 (helper)VKClient.call is the actual HTTP caller that executes the VK API method (e.g., 'friends.search') against the VK API endpoint.
async call(method, params = {}, { timeoutMs = 30000 } = {}) { const normalized = {}; for (const [k, v] of Object.entries(params)) { if (v === undefined || v === null) continue; if (typeof v === 'boolean') { normalized[k] = v ? '1' : '0'; } else if (Array.isArray(v)) { normalized[k] = v.join(','); } else { normalized[k] = String(v); } } const body = new URLSearchParams({ ...normalized, access_token: this.accessToken, v: this.apiVersion, }); const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), timeoutMs); try { const response = await fetch(`${this.baseUrl}/${method}`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: body.toString(), signal: controller.signal, }); const text = await response.text(); if (!response.ok) { const safeText = text.replace(this.accessToken, '***'); throw new Error(`VK HTTP Error ${response.status}: ${safeText}`); } let data; try { data = JSON.parse(text); } catch { const safeText = text.replace(this.accessToken, '***'); throw new Error(`VK API returned non-JSON response: ${safeText}`); } if (data.error) { const code = data.error.error_code; const msg = data.error.error_msg; throw new Error(`VK API Error ${code}: ${msg}`); } return data.response; } catch (err) { if (err.name === 'AbortError') { throw new Error(`VK API timeout after ${timeoutMs}ms for method ${method}`); } throw err; } finally { clearTimeout(timeout); } }