AgentStack
MCP verified MIT Self-run

Jurnal Mcp

mcp-teguhcanggu-jurnal-mcp · by Teguhcanggu

Read-only MCP server for Mekari Jurnal accounting API (jurnal.id) — 27 tools, HMAC-SHA256 auth, multi-profile support, financial-report PDF generator.

No reviews yet
0 installs
3 views
0.0% view→install

Install

$ agentstack add mcp-teguhcanggu-jurnal-mcp

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README — it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-teguhcanggu-jurnal-mcp)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming — see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps — measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Jurnal Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

jurnal-mcp

[](LICENSE) [](https://www.python.org/)

Read-only Model Context Protocol server for the Mekari Jurnal accounting API. Lets MCP clients (Claude Code, Claude Desktop, etc.) read contacts, invoices, journal entries, and financial reports across one or more Jurnal companies.

> Read-only by design. No tool in this server creates, updates, or > deletes data in Jurnal. Use it to read accounting facts and let the AI > assemble accurate reports from them.

Features

  • 27 MCP tools covering master data, transactions, and 8 financial reports

(P&L, balance sheet, cash flow, trial balance, GL, aged AP/AR, executive summary)

  • HMAC-SHA256 request signing per Mekari's official auth scheme — stateless,

no token refresh, no OAuth flow

  • Multi-profile support: connect several Jurnal companies/credentials and

switch per call via a profile argument

  • Python 3.11+, uv packaged,

FastMCP transport

Requirements

  • Python ≥ 3.11
  • uv for dependency management
  • A Mekari developer application with Client ID + Client Secret per

Jurnal company you want to access. Apply or check yours at developers.mekari.com.

Install

git clone https://github.com//jurnal-mcp.git
cd jurnal-mcp/jurnal-mcp-server
uv sync

Configure

Copy the example env file and fill in your credentials:

cp ../.env.example .env   # path is relative to jurnal-mcp-server/

Edit jurnal-mcp-server/.env:

JURNAL_PROFILE_MAIN_CLIENT_ID=
JURNAL_PROFILE_MAIN_CLIENT_SECRET=
JURNAL_DEFAULT_PROFILE=main

To connect more than one Jurnal company, add more profiles by repeating the pattern with a different ``:

JURNAL_PROFILE_BRANCH_A_CLIENT_ID=...
JURNAL_PROFILE_BRANCH_A_CLIENT_SECRET=...
JURNAL_PROFILE_BRANCH_B_CLIENT_ID=...
JURNAL_PROFILE_BRANCH_B_CLIENT_SECRET=...

` is any uppercase identifier you choose. Each tool accepts an optional profile argument that selects which credentials to use; calls without an explicit profile fall back to JURNALDEFAULTPROFILE`.

> Security: keep .env gitignored, restrict permissions > (chmod 600 .env), and never commit credentials. The .gitignore > already excludes .env.

Run as a standalone MCP server

cd jurnal-mcp-server
uv run main.py

The server speaks MCP over stdio.

Add to Claude Code

Add this entry to your ~/.claude/mcp.json (or the equivalent for your MCP host):

{
  "mcpServers": {
    "jurnal": {
      "type": "stdio",
      "command": "/path/to/uv",
      "args": [
        "--directory",
        "/absolute/path/to/jurnal-mcp/jurnal-mcp-server",
        "run",
        "main.py"
      ],
      "env": {
        "JURNAL_PROFILE_MAIN_CLIENT_ID": "...",
        "JURNAL_PROFILE_MAIN_CLIENT_SECRET": "...",
        "JURNAL_DEFAULT_PROFILE": "main"
      }
    }
  }
}

You can also keep credentials in jurnal-mcp-server/.env and omit the env block — the server loads .env automatically on startup.

Available tools (27)

All tools are read-only (GET). Every tool takes an optional profile: str | None argument; omit to use JURNAL_DEFAULT_PROFILE.

Auth & discovery

| Tool | Endpoint | Description | |------|----------|-------------| | list_profiles | (local) | Profiles discovered from env vars + the default | | whoami | GET /api/v1/users/me | Authenticated Mekari user | | get_active_company | GET /api/v1/companies/active | Active company for the credentials | | list_companies | GET /api/v1/companies | Companies accessible to the credentials |

Master data

| Tool | Endpoint | |------|----------| | list_contacts(contact_index?) | GET /api/v1/contacts | | get_contact(id) | GET /api/v1/contacts/{id} | | list_customers(page?, page_size?, sort_key?, sort_order?) | GET /api/v1/customers | | list_vendors(page?, page_size?, sort_key?, sort_order?) | GET /api/v1/vendors | | list_products(include_archive?) | GET /api/v1/products | | list_accounts(include_archive?) | GET /api/v1/accounts (chart of accounts) |

Transactions

| Tool | Endpoint | |------|----------| | list_sales_invoices(page?, page_size?, sort_key?, sort_order?) | GET /api/v1/sales_invoices | | get_sales_invoice(id) | GET /api/v1/sales_invoices/{id} | | list_purchase_invoices(page?, page_size?, sort_key?, sort_order?) | GET /api/v1/purchase_invoices | | get_purchase_invoice(id) | GET /api/v1/purchase_invoices/{id} | | list_journal_entries() | GET /api/v1/journal_entries | | get_journal_entry(id) | GET /api/v1/journal_entries/{id} | | list_expenses() | GET /api/v1/expenses | | list_receive_payments() | GET /api/v1/receive_payments | | list_purchase_payments() | GET /api/v1/purchase_payments |

Financial reports

All report endpoints accept dates in dd/mm/yyyy form (e.g. "01/01/2026").

| Tool | Endpoint | |------|----------| | get_profit_and_loss(start_date, end_date, period?, compare_type?) | GET /api/v1/profit_and_loss | | get_balance_sheet(end_date, compare?, period?, compare_type?) | GET /api/v1/balance_sheet | | get_cash_flow(start_date, end_date, period?, compare_type?) | GET /api/v1/cash_flow | | get_general_ledger(start_date, end_date, account_id?, compare_type?) | GET /api/v1/general_ledger | | get_trial_balance(start_date?, end_date?, period?, compare_type?) | GET /api/v1/trial_balance | | get_aged_payables(end_date?, period?, compare_type?) | GET /api/v1/aged_payables | | get_aged_receivables(end_date?, period?, compare_type?) | GET /api/v1/aged_receivables | | get_executive_summary(start_date?, end_date?, period?, compare_type?) | GET /api/v1/executive_summary |

compare_type accepts: custom, day, week, month, year, yesterday, last_week, last_month, last_year.

Authentication scheme (HMAC)

Every request is signed with HMAC-SHA256 over a canonical string:

date: 
  HTTP/1.1

The two lines are joined by \n. The signature is base64-encoded and sent in the Authorization header alongside Date:

Date: Wed, 29 Apr 2026 03:00:00 GMT
Authorization: hmac username="", algorithm="hmac-sha256", headers="date request-line", signature=""

Mekari rejects requests whose Date differs from server time by more than 300 seconds. Make sure the host clock is in sync (e.g. via NTP).

This server only signs GET requests, so the Digest header that Mekari requires for write methods is not sent. Adding write tools is intentionally out of scope.

References:

Multi-profile usage examples

# In an MCP client conversation:
# 1) Discover profiles
list_profiles()
# -> {"profiles": ["branch_a", "branch_b", "main"], "default": "main"}

# 2) Read a specific company's profit & loss (dates in dd/mm/yyyy)
get_profit_and_loss(
    profile="branch_a",
    start_date="01/01/2026",
    end_date="31/03/2026",
)

# 3) List contacts from another profile
list_contacts(profile="branch_b")

If only one Mekari Client ID gives access to multiple companies, you can configure a single profile and skip the profile argument entirely.

Development

Install dev dependencies and run the offline test suite:

cd jurnal-mcp-server
uv sync --all-extras --dev
uv run pytest tests/ -v

The test suite verifies the HMAC string-to-sign matches Mekari's reference implementation, exercises the path/query construction, and the profile resolver. It does not call the live API.

Verifying tools end-to-end

After credentials are in place, a quick smoke test:

uv run python -c "from jurnal import JurnalClient; print(JurnalClient.from_profile().get('/api/v1/users/me'))"

A 200 response with user info confirms credentials and signing work. A 401 usually means a clock skew over 300 seconds, a wrong client ID, or a secret with whitespace.

Status & limitations

  • Read-only. No write tools are exposed; the server signs only GET.
  • Date format. All report tools take dates in dd/mm/yyyy form. The

swagger spec only documents this format explicitly for general_ledger, but in practice the same format works across the report endpoints, so this server uses it uniformly for predictability.

  • No retry/backoff on rate limits yet; add as needed for your workload.

License

MIT — see [LICENSE](LICENSE).

Acknowledgements

for the reference signing flow.

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.