# BNM Malaysia MCP Server (`bluefirec300/bnm-mcp-server`) Actor

MCP server exposing Bank Negara Malaysia's free public Open API as tools: USD/MYR currency conversion, Kijang Emas gold valuation, and an OPR/FX/gold economic snapshot.

- **URL**: https://apify.com/bluefirec300/bnm-mcp-server.md
- **Developed by:** [MP K](https://apify.com/bluefirec300) (community)
- **Categories:** Developer tools, AI
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## BNM Malaysia MCP Server

An [MCP](https://modelcontextprotocol.io) server that wraps [Bank Negara Malaysia's (BNM) free public Open API](https://apikijangportal.bnm.gov.my/openapi), exposing Malaysian currency, gold, and interest rate data as tools for AI agents. It runs as an [Apify Actor in Standby mode](https://docs.apify.com/platform/actors/development/programming-interface/standby), so it behaves like a normal always-on HTTP API rather than a one-shot batch run, and it is monetized with [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing — you only pay for successful tool calls.

This is an independent, unofficial integration. It is not affiliated with or endorsed by Bank Negara Malaysia. Data is provided as-is from BNM's public API with no guarantee of accuracy or availability; do not use it as the sole basis for financial decisions.

### Connecting

Once deployed, the Actor exposes a standard streamable-HTTP MCP endpoint at:

```
https://<your-username>--bnm-mcp-server.apify.actor/mcp
```

Add that URL to any MCP-compatible client (Claude, Cursor, etc.) using your Apify API token for authorization. No run input is required — the Actor only serves the MCP endpoint.

### Tools

#### `convert_currency`

Converts an amount between two currencies.

| Parameter | Type | Description |
|---|---|---|
| `amount` | number | Amount to convert |
| `from_currency` | string | 3-letter source currency code (e.g. `USD`, `MYR`, `EUR`) |
| `to_currency` | string | 3-letter target currency code |

For USD↔MYR, the rate is BNM's official **KL USD Reference Rate** for the current date. For any other currency pair, the amount is triangulated through USD: each currency's value is first expressed in USD (using BNM's daily commercial exchange rate table for third currencies, and the KL reference rate for the USD/MYR leg), then converted to the target currency. Returns the converted amount, the effective rate used, and the date the rate was published.

#### `kijang_emas_value`

Values a weight of gold in Malaysian Ringgit using BNM's latest **Kijang Emas** gold coin price.

| Parameter | Type | Description |
|---|---|---|
| `weight` | number | Weight of gold |
| `unit` | `"gram"` | `"oz"` | Unit of the weight (troy ounce for `oz`) |

The unit price is the average of BNM's published buying and selling price for the 1 oz Kijang Emas denomination, linearly scaled to the requested weight (1 troy oz = 31.1034768 g). Returns the estimated value in MYR, the unit price used, and the price's effective date.

#### `my_economic_snapshot`

Takes no input. Returns a single snapshot combining:

- **OPR** — the current Overnight Policy Rate and its date
- **USD/MYR reference rate** — BNM's KL USD Reference Rate and its date
- **Kijang Emas gold price** — the latest 1 oz buying/selling price and its date

### Pricing

This Actor uses pay-per-event billing — no charge for idle Standby time, only for successful tool calls:

| Event | Description | Default price |
|---|---|---|
| `convert_currency_call` | One successful currency conversion | $0.01 |
| `kijang_emas_call` | One successful gold valuation | $0.01 |
| `snapshot_call` | One successful economic snapshot | $0.02 |

Failed calls (e.g. BNM API errors, unsupported currency, markets closed) are **not** charged. Prices shown are the template defaults defined in `.actor/pay_per_event.json`; the live prices for the published Actor are managed in Apify Console.

### Error handling

BNM's API returns HTTP 404 both for invalid dates and for dates with no data (e.g. weekends and public holidays, when FX/gold markets are closed). All tools catch upstream failures — network errors, non-200 responses, unsupported currency codes — and return a normal MCP tool result with `isError: true` and a human-readable message, instead of crashing the server or the request.

### Data source

All data comes from BNM's public Open API at `https://api.bnm.gov.my/public/` (requires the header `Accept: application/vnd.BNM.API.v1+json`):

- `GET /kl-usd-reference-rate/date/{date}` — KL USD/MYR reference rate
- `GET /exchange-rate` — daily commercial exchange rates for ~26 other currencies against MYR
- `GET /kijang-emas` — Kijang Emas gold coin price
- `GET /opr` — Overnight Policy Rate

### Local development

```bash
npm install
npm run start:dev
```

The server listens on port 3000 by default (override with `APIFY_CONTAINER_PORT`), serving the MCP endpoint at `POST /mcp`. Pay-per-event charging is a no-op outside the Apify platform unless you set `ACTOR_TEST_PAY_PER_EVENT=true`, which logs charges to a local `charging-log` dataset instead of billing anyone.

### Deployment

```bash
apify push
```

Standby mode is enabled via `"usesStandbyMode": true` in `.actor/actor.json`. After pushing, enable pay-per-event pricing and set live prices for the Actor in Apify Console under the Actor's **Monetization** settings.

# Actor input Schema

## Actor input object example

```json
{}
```

# Actor output Schema

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("bluefirec300/bnm-mcp-server").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("bluefirec300/bnm-mcp-server").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call bluefirec300/bnm-mcp-server --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bluefirec300/bnm-mcp-server"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/kogJ9STzvuUly47e6/builds/1UE0Me43gssdL3mPY/openapi.json
