Skip to main content
Glama
ErickWendel

Erick Wendel Contributions MCP

by ErickWendel

get_talks

Retrieve and filter Erick Wendel's conference talks by ID, title, language, location, or year with pagination and grouping options.

Instructions

Get a list of talks with optional filtering and pagination.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idNoFilter talks by ID
titleNoFilter talks by title
languageNoFilter talks by language (e.g., 'spanish', 'english', 'portuguese' or direct codes like 'es', 'en', 'pt-br')
cityNoFilter talks by city
countryNoFilter talks by country
yearNoFilter talks by year
skipNoNumber of talks to skip
limitNoMaximum number of talks to return
count_onlyNoIf true, returns only the count without talk details
group_byNoGroup counts by a specific field (language, country, city)

Implementation Reference

  • The primary handler function for the 'get_talks' tool. It processes input parameters, calls GraphQL queries via helpers, handles special cases like year filtering and grouping, and returns formatted MCP response.
    handler: async (params: TalksParams): Promise<McpResponse> => {
      try {
        const { id, title, language, city, country, year, skip, limit, count_only, group_by } = params;
        
        // Handle year-specific filtering
        if (year) {
          const allTalks = await fetchTalksByYear({ id, title, language, city, country, year });
          
          if (count_only) {
            let response = `Total talks in ${year}: ${allTalks.length}`;
            
            if (group_by) {
              const counts = calculateGroupCounts(allTalks, group_by);
              response += formatGroupCounts(counts, group_by);
            }
    
            const content: McpTextContent = {
              type: "text",
              text: response
            };
    
            return {
              content: [content],
            };
          }
    
          // Apply pagination to filtered results
          const paginatedTalks = allTalks.slice(skip || 0, (skip || 0) + (limit || 10));
    
          const content: McpTextContent = {
            type: "text",
            text: `Talks Results for ${year}:\n\n${JSON.stringify({ 
              totalCount: allTalks.length,
              retrieved: paginatedTalks.length,
              talks: paginatedTalks 
            }, null, 2)}`
          };
    
          return {
            content: [content],
          };
        }
    
        // Regular query without year filtering
        const result = await fetchTalks({ id, title, language, city, country, skip, limit, count_only });
    
        if (!result.getTalks) {
          throw new Error('No results returned from API');
        }
    
        if (count_only) {
          let response = `Total talks: ${result.getTalks.totalCount}`;
          
          if (group_by && result.getTalks.talks) {
            const counts = calculateGroupCounts(result.getTalks.talks, group_by);
            response += formatGroupCounts(counts, group_by);
          }
    
          const content: McpTextContent = {
            type: "text",
            text: response
          };
    
          return {
            content: [content],
          };
        }
    
        const content: McpTextContent = {
          type: "text",
          text: `Talks Results:\n\n${JSON.stringify(result.getTalks, null, 2)}`
        };
    
        return {
          content: [content],
        };
      } catch (error) {
        throw new Error(`Failed to fetch talks: ${error.message}`);
      }
    }
  • Zod-based input schema defining all parameters for the get_talks tool, including filters, pagination, and grouping options.
    parameters: {
      id: z.string().optional().describe("Filter talks by ID"),
      title: z.string().optional().describe("Filter talks by title"),
      language: z.string().optional().describe("Filter talks by language (e.g., 'spanish', 'english', 'portuguese' or direct codes like 'es', 'en', 'pt-br')"),
      city: z.string().optional().describe("Filter talks by city"),
      country: z.string().optional().describe("Filter talks by country"),
      year: z.number().optional().describe("Filter talks by year"),
      skip: z.number().optional().default(0).describe("Number of talks to skip"),
      limit: z.number().optional().default(10).describe("Maximum number of talks to return"),
      count_only: z.boolean().optional().default(false).describe("If true, returns only the count without talk details"),
      group_by: z.string().optional().describe("Group counts by a specific field (language, country, city)"),
    },
  • src/index.ts:21-26 (registration)
    Registration of the get_talks tool with the MCP server using the tool() method, passing name, description, parameters, and handler.
    server.tool(
      getTalksTool.name,
      getTalksTool.description,
      getTalksTool.parameters,
      getTalksTool.handler
    );
  • Core helper function that executes the GraphQL query to fetch talks data from the API, used by the tool handler.
    export async function fetchTalks(params: {
      id?: string;
      title?: string;
      language?: string;
      city?: string;
      country?: string;
      skip?: number;
      limit?: number;
      count_only?: boolean;
    }): Promise<TalksResponse> {
      const { id, title, language, city, country, skip, limit, count_only } = params;
      const languageCode = getLanguageCode(language);
    
      return await client.query({
        getTalks: {
          __args: {
            _id: id,
            title,
            language: languageCode,
            city,
            country,
            skip,
            limit: count_only ? 0 : limit,
          },
          totalCount: true,
          retrieved: true,
          processedIn: true,
          talks: count_only ? {
            language: true,
            location: {
              country: true,
              city: true,
            }
          } : {
            _id: true,
            title: true,
            abstract: true,
            type: true,
            event: {
              link: true,
              name: true,
            },
            slides: true,
            video: true,
            tags: true,
            location: {
              country: true,
              city: true,
            },
            language: true,
            date: true,
          },
        },
      }) as TalksResponse;
    }
  • Utility function to calculate counts of talks grouped by language, country, or city.
    function calculateGroupCounts(talks: Talk[], groupBy: string): Map<string, number> {
      const counts = new Map<string, number>();
      
      talks.forEach(talk => {
        if (!talk) return;
        
        let value = '';
        switch(groupBy) {
          case 'language':
            value = talk.language || 'unknown';
            break;
          case 'country':
            value = talk.location?.country || 'unknown';
            break;
          case 'city':
            value = talk.location?.city || 'unknown';
            break;
          default:
            return;
        }
        counts.set(value, (counts.get(value) || 0) + 1);
      });
    
      return counts;
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It mentions 'optional filtering and pagination' but lacks critical behavioral details: what the return format looks like (e.g., list structure, fields included), whether it's a safe read operation (implied by 'Get' but not explicit), error handling, rate limits, or authentication requirements. For a tool with 10 parameters and no annotation coverage, this is insufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence: 'Get a list of talks with optional filtering and pagination.' It's front-loaded with the core purpose and wastes no words. Every part of the sentence earns its place by highlighting key features.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (10 parameters, no annotations, no output schema), the description is incomplete. It lacks details on return values, error conditions, behavioral traits (e.g., whether it's idempotent or safe), and usage context relative to siblings. For a list-retrieval tool with rich filtering options, more guidance is needed to help an agent use it effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents all 10 parameters. The description adds minimal value beyond the schema—it mentions 'optional filtering and pagination,' which aligns with parameters like 'skip,' 'limit,' and filtering fields, but doesn't provide additional syntax, format details, or usage examples. Baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Get a list of talks with optional filtering and pagination.' It specifies the verb ('Get') and resource ('talks'), and mentions key capabilities (filtering, pagination). However, it doesn't explicitly differentiate from sibling tools like 'get_posts' or 'get_videos' beyond the resource type.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It mentions 'optional filtering and pagination' but doesn't specify scenarios, prerequisites, or exclusions. With sibling tools like 'get_posts' and 'get_videos' available, there's no indication of when to choose talks over posts or videos.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/ErickWendel/erickwendel-contributions-mcp'

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