Skip to main content
Glama

PBS MCP AI Enabled API Server

pbsApi.ts6.16 kB
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; import { z } from 'zod'; /** * PBS API tool * - Interacts with the Pharmaceutical Benefits Scheme (PBS) API * - Provides access to PBS data including medicine listings, pricing, and availability * - Uses the provided subscription key for authentication */ export const pbsApiToolName = "pbs_api"; export const pbsApiToolDescription = "Access the Australian Pharmaceutical Benefits Scheme (PBS) API to retrieve information about medicines, pricing, and availability."; // Default subscription key for unregistered public users const DEFAULT_SUBSCRIPTION_KEY = "2384af7c667342ceb5a736fe29f1dc6b"; // Base URL for the PBS API const PBS_API_BASE_URL = "https://data-api.health.gov.au/pbs/api/v3"; export const PbsApiToolSchema = z.object({ endpoint: z.string().describe('The specific PBS API endpoint to access (e.g., "prescribers", "item-overview")'), method: z.enum(['GET', 'POST']).default('GET') .describe('HTTP method to use (GET is recommended for most PBS API operations)'), params: z.record(z.string()).optional() .describe('Query parameters to include in the request (e.g., {"get_latest_schedule_only": "true"})'), subscriptionKey: z.string().optional() .describe('Custom subscription key (if not provided, the default public key will be used)'), timeout: z.number().default(30000) .describe('Request timeout in milliseconds') }); // Format the response in a readable way function formatResponse(response: AxiosResponse): { content: { type: string; text: string }[] } { // Extract rate limit information from headers const rateLimitLimit = response.headers['x-rate-limit-limit']; const rateLimitRemaining = response.headers['x-rate-limit-remaining']; const rateLimitReset = response.headers['x-rate-limit-reset']; const formattedResponse: Record<string, any> = { status: response.status, statusText: response.statusText, headers: response.headers, data: response.data }; // Add rate limit information if available if (rateLimitLimit || rateLimitRemaining || rateLimitReset) { formattedResponse.rateLimit = { limit: rateLimitLimit, remaining: rateLimitRemaining, reset: rateLimitReset }; } return { content: [ { type: "text", text: "```json\n" + JSON.stringify(formattedResponse, null, 2) + "\n```" } ] }; } // Format error response function formatErrorResponse(error: any): { content: { type: string; text: string }[] } { const errorResponse: Record<string, any> = { error: true }; if (error.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx errorResponse.status = error.response.status; errorResponse.statusText = error.response.statusText; errorResponse.headers = error.response.headers; errorResponse.data = error.response.data; // Extract rate limit information from headers const rateLimitLimit = error.response.headers['x-rate-limit-limit']; const rateLimitRemaining = error.response.headers['x-rate-limit-remaining']; const rateLimitReset = error.response.headers['x-rate-limit-reset']; if (rateLimitLimit || rateLimitRemaining || rateLimitReset) { errorResponse.rateLimit = { limit: rateLimitLimit, remaining: rateLimitRemaining, reset: rateLimitReset }; } } else if (error.request) { // The request was made but no response was received errorResponse.message = 'No response received from server'; errorResponse.request = 'Request was sent but no response was received'; } else { // Something happened in setting up the request errorResponse.message = error.message; } // Add helpful messages for common error codes if (errorResponse.status === 401) { errorResponse.helpMessage = "Authentication failed. The PBS API requires proper authentication. Check if you need to register for API access at https://dev.pbs.gov.au/contacts.html"; } else if (errorResponse.status === 415) { errorResponse.helpMessage = "Unsupported Media Type. Make sure to set the Accept header to 'application/json'."; } else if (errorResponse.status === 429) { errorResponse.helpMessage = "Rate limit exceeded. The PBS API has a limit of 5 requests per time window. Wait for the rate limit to reset before making more requests."; } else if (errorResponse.status === 400) { errorResponse.helpMessage = "Bad Request. Check if all required parameters are provided correctly."; } return { content: [ { type: "text", text: "```json\n" + JSON.stringify(errorResponse, null, 2) + "\n```" } ] }; } // Construct the full URL for the endpoint function constructUrl(endpoint: string): string { // If endpoint is empty, return the base API URL if (!endpoint) { return PBS_API_BASE_URL; } // Make sure the endpoint starts with a slash if it doesn't already const formattedEndpoint = endpoint.startsWith('/') ? endpoint : `/${endpoint}`; return `${PBS_API_BASE_URL}${formattedEndpoint}`; } // PBS API tool implementation export async function runPbsApiTool(args: z.infer<typeof PbsApiToolSchema>) { try { const endpoint = args.endpoint || ''; console.error(`Accessing PBS API endpoint: ${args.method} ${endpoint}`); // Use the provided subscription key or fall back to the default const subscriptionKey = args.subscriptionKey || DEFAULT_SUBSCRIPTION_KEY; // Construct the full URL const url = constructUrl(endpoint); // Configure request const config: AxiosRequestConfig = { method: args.method, url: url, headers: { 'Subscription-Key': subscriptionKey, 'Accept': 'application/json' }, params: args.params || {}, timeout: args.timeout }; // Make the request const response = await axios(config); return formatResponse(response); } catch (error) { console.error('PBS API error:', error); return formatErrorResponse(error); } }

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/matthewdcage/pbs-mcp-server'

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