Skip to main content
Glama

disease_surveillance

Retrieve case counts and trends for diseases using CDC surveillance data, filtered by condition, ICD-10 code, or state.

Instructions

Look up disease surveillance data including case counts and trends by condition and geography. Source: CDC National Notifiable Diseases Surveillance System (public domain).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
conditionNoDisease or condition name (e.g., "Hepatitis A", "Salmonellosis")
codeNoICD-10 code (auto-mapped to condition name)
stateNo2-letter state code to filter by geography

Implementation Reference

  • src/tools.js:195-253 (registration)
    Tool registration definition with name, description, schema (Zod), price, and endpoint URL.
      // --- Disease Surveillance (CDC NNDSS — free, no license) ---
      {
        name: 'disease_surveillance',
        description: 'Look up disease surveillance data including case counts and trends by condition and geography. Source: CDC National Notifiable Diseases Surveillance System (public domain).',
        price: '$0.02',
        endpoint: '/agent/v1/surveillance/disease',
        schema: {
          condition: z.string().optional().describe('Disease or condition name (e.g., "Hepatitis A", "Salmonellosis")'),
          code: z.string().optional().describe('ICD-10 code (auto-mapped to condition name)'),
          state: z.string().optional().describe('2-letter state code to filter by geography'),
        },
      },
    
      // --- Data Enrichment ---
      {
        name: 'provider_search',
        description: 'Search the NPI provider directory. Find healthcare providers by name, specialty, or location.',
        price: '$0.005',
        endpoint: '/agent/v1/providers/search',
        schema: {
          firstName: z.string().optional(),
          lastName: z.string().optional(),
          organizationName: z.string().optional(),
          taxonomy: z.string().optional().describe('Provider taxonomy/specialty code'),
          city: z.string().optional(),
          state: z.string().optional().describe('2-letter state code'),
          limit: z.number().optional().describe('Max results (default 10, max 50)'),
        },
      },
      {
        name: 'provider_enrich',
        description: 'AI-enriched provider intelligence from NPI number. Returns practice details, specialties, affiliations, and market context.',
        price: '$0.05',
        endpoint: '/agent/v1/providers/enrich',
        schema: {
          npi: z.string().describe('10-digit NPI number'),
        },
      },
      {
        name: 'drug_enrich',
        description: 'Drug information enrichment via OpenFDA. Returns drug details, indications, interactions, and AI analysis.',
        price: '$0.03',
        endpoint: '/agent/v1/drugs/enrich',
        schema: {
          drugName: z.string().describe('Drug name (brand or generic, min 2 chars)'),
          searchField: z.enum(['brand_name', 'generic_name']).optional().describe('Search by brand or generic name'),
        },
      },
      {
        name: 'market_analysis',
        description: 'Healthcare specialty market analysis for a specific state. Returns provider density, competition metrics, and market opportunity data.',
        price: '$0.10',
        endpoint: '/agent/v1/market/analysis',
        schema: {
          state: z.string().describe('2-letter state code (e.g., "TX", "CA")'),
          specialty: z.string().describe('Medical specialty (e.g., "cardiology", "orthopedics")'),
        },
      },
    ];
  • Generic handler that registers all tools via iteration, calling the tool's endpoint via fetch and returning the response.
      for (const tool of MCP_TOOLS) {
        s.tool(tool.name, tool.description, tool.schema, async (params) => {
          const toolDef = getToolByName(tool.name);
          if (!toolDef) {
            return { content: [{ type: 'text', text: `Unknown tool: ${tool.name}` }], isError: true };
          }
          try {
            const response = await fetch(`${API_BASE_URL}${toolDef.endpoint}`, {
              method: 'POST',
              headers: {
                'Content-Type': 'application/json',
                ...(API_KEY && { 'X-API-Key': API_KEY }),
                'X-Agent-ID': 'mcp-client',
                'User-Agent': '@mymedi-ai/mcp-server/1.2.1',
              },
              body: JSON.stringify(params),
            });
            if (response.status === 402) {
              const paymentInfo = await response.json();
              return {
                content: [{ type: 'text', text: JSON.stringify({
                  error: 'payment_required',
                  message: `This tool costs ${toolDef.price} per call. Register at ${API_BASE_URL}/bot-marketplace/register for an API key with 10 free starter credits, or pay per call with on-chain USDC (no signup) via the x402 protocol.`,
                  price: toolDef.price, register: `${API_BASE_URL}/bot-marketplace/register`, ...paymentInfo,
                }, null, 2) }], isError: true,
              };
            }
            if (!response.ok) {
              const error = await response.json().catch(() => ({ message: response.statusText }));
              return { content: [{ type: 'text', text: JSON.stringify({ error: true, status: response.status, ...error }, null, 2) }], isError: true };
            }
            const data = await response.json();
            const creditsSpent = response.headers.get('X-Credits-Spent');
            const creditsRemaining = response.headers.get('X-Credits-Remaining');
            if (creditsSpent) {
              data._billing = { creditsSpent: parseInt(creditsSpent, 10), creditsRemaining: creditsRemaining ? parseInt(creditsRemaining, 10) : undefined, priceUSD: toolDef.price };
            }
            return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
          } catch (err) {
            return { content: [{ type: 'text', text: JSON.stringify({ error: true, message: err.message, hint: 'Ensure MCP_API_BASE_URL and MCP_API_KEY environment variables are set.' }, null, 2) }], isError: true };
          }
        });
      }
      return s;
    }
  • Zod input schema for disease_surveillance: condition (string), code (string), state (string).
      schema: {
        condition: z.string().optional().describe('Disease or condition name (e.g., "Hepatitis A", "Salmonellosis")'),
        code: z.string().optional().describe('ICD-10 code (auto-mapped to condition name)'),
        state: z.string().optional().describe('2-letter state code to filter by geography'),
      },
    },
  • Helper function to look up a tool definition by name, used by the generic handler.
    export function getToolByName(name) {
      return MCP_TOOLS.find((t) => t.name === name);
    }
Behavior3/5

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

With no annotations, the description carries the full burden. It mentions the data source (CDC public domain) which is helpful, but does not disclose any behavioral traits like rate limits, data freshness, or behavior on missing results.

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 two sentences, no wasted words. The first sentence states the main purpose, the second provides the source. Well structured and concise.

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

Completeness3/5

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

No output schema is provided, so the description should give some idea of return values. It mentions case counts and trends but lacks detail on format or structure. For a simple lookup, this is adequate but not complete.

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% with clear descriptions for condition, code, and state. The description adds that the tool returns case counts and trends, but does not add significant meaning beyond the schema.

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 looks up disease surveillance data (case counts, trends) by condition and geography. It distinguishes from siblings like code_lookup or drug_lookup by specifying public health data from CDC. However, the verb 'Look up' is somewhat generic.

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?

No guidance is provided on when to use this tool versus alternatives. The description implies it is for epidemiological data but does not explicitly state when it should be chosen over similar tools.

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/MyMedi-AI/mymedi-ai-mcp-server'

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