vk_photos_get_user_photos
Get photos where a specified user is tagged. Supports pagination, sorting by tag date, and optional likes field.
Instructions
Returns a list of photos in which a user is tagged.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | No | User ID. | |
| offset | No | Offset needed to return a specific subset of photos. By default, '0'. | |
| count | No | Number of photos to return. Maximum value is 1000. | |
| extended | No | '1' - to return an additional 'likes' field, '0' - (default) | |
| sort | No | Sort order: '1' - by date the tag was added in ascending order, '0' - by date the tag was added in descending order |
Implementation Reference
- src/tool-registry.js:3-8 (registration)The getToolName function generates the tool name 'vk_photos_get_user_photos' from the VK API method 'photos.getUserPhotos' by replacing dots with underscores and converting to lowercase.
function getToolName(methodName) { return `vk_${methodName .replace(/\./g, '_') .replace(/([a-z0-9])([A-Z])/g, '$1_$2') .toLowerCase()}`; } - src/tool-registry.js:27-73 (handler)The buildHandler function creates a generic handler that maps tool names to VK API methods and calls vkClient.call(). When 'vk_photos_get_user_photos' is called, it maps to 'photos.getUserPhotos' and executes via the VK API client.
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/param-converter.js:70-100 (schema)The buildInputSchema function dynamically builds input schemas from VK API method parameters. For 'vk_photos_get_user_photos', the schema is generated dynamically from the 'photos.getUserPhotos' method definition loaded from the VK API schema JSON.
export function buildInputSchema(parameters) { if (!parameters || parameters.length === 0) { return { type: 'object', properties: {}, additionalProperties: false, }; } const properties = {}; const required = []; for (const param of parameters) { properties[param.name] = convertParam(param); if (param.required === true) { required.push(param.name); } } const schema = { type: 'object', properties, additionalProperties: false, }; if (required.length > 0) { schema.required = required; } return schema; } - src/vk-client.js:1-69 (helper)The VKClient class handles the actual API call. When the handler invokes call('photos.getUserPhotos', args), this class sends a POST request to https://api.vk.com/method/photos.getUserPhotos with the access token.
export class VKClient { constructor(accessToken) { this.accessToken = accessToken; this.apiVersion = '5.199'; this.baseUrl = 'https://api.vk.com/method'; } 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); } } } - src/profiles.js:33-33 (registration)The 'photos.getUserPhotos' method is listed in the 'content_read' profile, which makes the generated tool 'vk_photos_get_user_photos' available when using that profile (mode: read).
'photos.getUserPhotos',