Skip to main content
Glama
reetp14

OpenAlex MCP Server

by reetp14

search_authors

Find academic authors and researchers by name, institution, ORCID, or other criteria using OpenAlex's comprehensive scholarly database.

Instructions

Search authors and researchers

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
searchNoFull-text search query
filterNoKey:value OpenAlex filters. Supports entity attributes (e.g., 'orcid', 'last_known_institution.id'), IDs, and convenience filters (e.g., 'display_name.search'). Example: 'has_orcid:true,last_known_institution.country_code:US'
sortNoSort field with optional :desc
pageNoPage number
per_pageNoResults per page (max 200)
cursorNoCursor for deep pagination
group_byNoGroup results by field
selectNoFields to return
sampleNoRandom sample size
seedNoRandom seed
mailtoNoEmail for rate limits
api_keyNoPremium API key

Implementation Reference

  • The handler function that implements the core logic of the 'search_authors' tool. It calls the makeOpenAlexRequest helper with the '/authors' endpoint and the input arguments, then formats the response as MCP content.
    export async function searchAuthors(args: any) {
        return {
            content: [{
                    type: "text",
                    text: JSON.stringify(await makeOpenAlexRequest("/authors", args), null, 2)
                }]
        };
    }
  • The input schema defining the parameters accepted by the 'search_authors' tool, including search, filter, pagination, and API options.
        inputSchema: {
            type: "object",
            properties: {
                search: { type: "string", description: "Full-text search query" },
                filter: { type: "string", description: "Key:value OpenAlex filters. Supports entity attributes (e.g., 'orcid', 'last_known_institution.id'), IDs, and convenience filters (e.g., 'display_name.search'). Example: 'has_orcid:true,last_known_institution.country_code:US'" },
                sort: { type: "string", description: "Sort field with optional :desc" },
                page: { type: "number", description: "Page number" },
                per_page: { type: "number", description: "Results per page (max 200)" },
                cursor: { type: "string", description: "Cursor for deep pagination" },
                group_by: { type: "string", description: "Group results by field" },
                select: { type: "string", description: "Fields to return" },
                sample: { type: "number", description: "Random sample size" },
                seed: { type: "number", description: "Random seed" },
                mailto: { type: "string", description: "Email for rate limits" },
                api_key: { type: "string", description: "Premium API key" }
            }
        }
    },
  • src/index.ts:283-284 (registration)
    The switch case in the CallToolRequest handler that registers and routes execution to the searchAuthors handler for 'search_authors' tool calls.
    case "search_authors":
        return await searchAuthors(args);
  • src/index.ts:78-98 (registration)
    The tool object in the ListTools response that registers 'search_authors' with its name, description, and schema.
    {
        name: "search_authors",
        description: "Search authors and researchers",
        inputSchema: {
            type: "object",
            properties: {
                search: { type: "string", description: "Full-text search query" },
                filter: { type: "string", description: "Key:value OpenAlex filters. Supports entity attributes (e.g., 'orcid', 'last_known_institution.id'), IDs, and convenience filters (e.g., 'display_name.search'). Example: 'has_orcid:true,last_known_institution.country_code:US'" },
                sort: { type: "string", description: "Sort field with optional :desc" },
                page: { type: "number", description: "Page number" },
                per_page: { type: "number", description: "Results per page (max 200)" },
                cursor: { type: "string", description: "Cursor for deep pagination" },
                group_by: { type: "string", description: "Group results by field" },
                select: { type: "string", description: "Fields to return" },
                sample: { type: "number", description: "Random sample size" },
                seed: { type: "number", description: "Random seed" },
                mailto: { type: "string", description: "Email for rate limits" },
                api_key: { type: "string", description: "Premium API key" }
            }
        }
    },
  • The shared helper function used by the search_authors handler (and other tools) to make HTTP requests to the OpenAlex API, handling query params, headers, auth, and errors.
    export async function makeOpenAlexRequest(endpoint: string, params: OpenAlexQueryParams = {}): Promise<any> {
        const queryString = buildQueryString(params);
        const url = `${OPENALEX_BASE_URL}${endpoint}${queryString ? '?' + queryString : ''}`;
        try {
            // Build User-Agent with mailto for polite pool access
            let userAgent = 'OpenAlex-MCP-Server/1.0.0 (https://github.com/openalex-mcp-server)';
            if (params.mailto) {
                userAgent += ` mailto:${params.mailto}`;
            }
            else {
                // Use environment variable for default email
                const defaultEmail = process.env.OPENALEX_DEFAULT_EMAIL || 'mcp-server@example.com';
                userAgent += ` mailto:${defaultEmail}`;
            }
    
            // Build headers
            const headers: Record<string, string> = {
                'Accept': 'application/json',
                'User-Agent': userAgent
            };
    
            // Add Bearer token - check parameter first, then environment variable
            const bearerToken = params.bearer_token || process.env.OPENALEX_BEARER_TOKEN;
            if (bearerToken) {
                headers['Authorization'] = `Bearer ${bearerToken}`;
            }
    
            const response = await axios.get(url, {
                headers,
                timeout: 30000
            });
            return response.data;
        }
        catch (error) {
            if (axios.isAxiosError(error)) {
                throw new Error(`OpenAlex API error: ${error.response?.status} - ${error.response?.statusText || error.message}`);
            }
            throw error;
        }
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/reetp14/openalex-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server