Skip to main content
Glama

provider_payments

Look up Sunshine Act data on payments from pharmaceutical and device companies to a physician by NPI, including total payments, type breakdown, and top payers.

Instructions

Look up pharmaceutical and device company payments to a physician (Sunshine Act data). Returns total payments, breakdown by type, and top paying companies. Source: CMS Open Payments (public domain).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
npiYes10-digit NPI number of the physician

Implementation Reference

  • Defines the provider_payments tool schema, including its name, description, price ($0.02), endpoint (/agent/v1/providers/payments), and input schema (requires a 10-digit NPI number). This is the tool definition using Zod for validation.
    // --- Physician Payments (CMS Open Payments — free, no license) ---
    {
      name: 'provider_payments',
      description: 'Look up pharmaceutical and device company payments to a physician (Sunshine Act data). Returns total payments, breakdown by type, and top paying companies. Source: CMS Open Payments (public domain).',
      price: '$0.02',
      endpoint: '/agent/v1/providers/payments',
      schema: {
        npi: z.string().describe('10-digit NPI number of the physician'),
      },
    },
  • src/index.js:17-63 (registration)
    Registers all tools (including provider_payments) from MCP_TOOLS via server.tool(). The handler makes an HTTP POST to the tool's endpoint (/agent/v1/providers/payments), passes the params as JSON body, and handles responses including 402 (payment required), errors, and success responses with billing info.
    function createMcpServer() {
      const s = new McpServer({ name: 'mymedi-ai', version: '1.2.1' });
      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;
    }
Behavior3/5

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

With no annotations provided, the description partially compensates by stating it is a lookup (read-only) and describing the output. However, it does not mention potential behavioral aspects such as rate limits, data year, or data refresh frequency. The description is adequate but not exhaustive.

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 concise with two sentences, no redundant information, and front-loads the core purpose. It efficiently conveys essential information without wasting words.

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

Completeness4/5

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

The description covers the key aspects: what the tool does, what it returns, and the data source. Given there is no output schema and no annotations, it provides a reasonable level of completeness for a simple lookup tool. However, it could be more complete by mentioning data year or pagination.

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?

The single parameter 'npi' is already well-described in the schema as a 10-digit NPI number. The description adds no extra meaning beyond the schema, so it meets the baseline for full schema coverage but does not enhance understanding.

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

Purpose5/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: looking up payments to a physician from pharmaceutical and device companies. It specifies the data source (Sunshine Act, CMS Open Payments) and what it returns (total payments, breakdown by type, top paying companies). This distinctively differentiates it from sibling tools like provider_enrich or provider_search.

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

Usage Guidelines3/5

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

The description implies the tool is for retrieving payment data but does not provide explicit guidance on when to use it versus alternatives, nor any prerequisites or exclusions. The context of being public domain is helpful, but without stating when not to use this tool, the agent may lack decision support.

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