Skip to main content
Glama

hilan-mcp

An MCP server for Hilan (Hilanet / חילן, חילנט) — pull your payslips and Form 106 into any AI assistant, for any Hilan tenant.

npm version npm downloads license node


There's no official Hilan API. hilan-mcp drives a real (headless) Chromium browser via Playwright to log in, then reuses that same authenticated session to call Hilan's internal endpoints and download PDFs — no fragile hand-rolled cookie replay, and no plaintext secrets stored anywhere.

Table of contents

Related MCP server: Israeli Bank MCP

Features

  • 📄 Payslips — structured Bruto/Neto/salary-parts data, plus the PDF, for any month in the tenant's history.

  • 🧾 Form 106 — annual tax summary PDFs, per year.

  • 🔐 Encrypted local storage — SQLCipher-encrypted SQLite, key never written to disk in plaintext; OS-native credential store (Keychain/DPAPI/Secret Service) support.

  • 🏢 Any Hilan tenant — login form fields are detected per-tenant instead of hardcoded to one employer.

  • 💬 Answers, not raw JSON — tools like query answer "how much did I earn in June?" straight from local data, no network round-trip.

  • 🔄 Self-updating awareness — the server checks for newer versions and lets your AI agent offer to update you, without needing its own UI.

How it works

This server drives a real (headless) Chromium browser via Playwright to log in, then reuses that same authenticated browser context's HTTP client (context.request) to call Hilan's internal .asmx JSON endpoints and download PDFs — so it automatically inherits whatever cookies/headers a real page load would have set up, instead of a fragile hand-rolled cookie replay.

Login form fields differ per Hilan tenant (some have 2 fields, some 3), so the login form is inspected fresh for each tenant the first time you ingest credentials, rather than hardcoded to one company.

Setup

0. If you're on npm 12 or newer

npm 12 blocks dependency install scripts unless you allow them, and one of this package's dependencies (better-sqlite3-multiple-ciphers, the encrypted SQLite engine) needs its install script to compile a native binding. Without it, setup appears to succeed and then every tool that touches the database fails. Allow it once, for all future npx and global installs:

npm config set allow-scripts=better-sqlite3-multiple-ciphers --location=user

Or per install, if you'd rather not set it globally:

npm install -g --allow-scripts=better-sqlite3-multiple-ciphers hilan-mcp

On npm 11 and older this isn't needed — install scripts still run by default. Check with npm --version.

1. Register a tenant and enter credentials

Run this yourself, directly in your own terminal — never paste real credentials into an AI chat. It installs the Chromium browser Playwright needs (one-time), launches a headless browser, detects your tenant's actual login fields, and prompts you for each one (passwords are masked). No local clone or npm install needed — npx fetches the package on the fly:

npx hilan-mcp setup --tenant amdocs        # tenant subdomain
# or
npx hilan-mcp setup --tenant 5227          # numeric org code, resolved automatically

If you already have the package installed some other way, the equivalent lower-level command is npx hilan-mcp ingest-creds --tenant <...>setup just also handles the one-time Chromium install first.

The first time you run this you'll be asked to set an encryption key for the local database (min 6 characters) — this key is never written to disk in plaintext.

For the MCP server to open the database on its own (without a human present to respond to a prompt every time), it looks for the key in this order:

  1. OS credential store (recommended) — run npx hilan-mcp setup-key once, yourself, in your own terminal. You'll be asked to type a key (or press Enter to generate a strong random one), and it's stored in your OS's native secure storage: macOS Keychain (verified — same file that holds your Wi-Fi/browser passwords, silent, no dialogs), Windows (DPAPI, tied to your Windows user account), or Linux (Secret Service / secret-tool, needs a keyring daemon like GNOME Keyring or KWallet). Nothing ends up in any config file at all.

  2. HILAN_DB_KEY env var — set it in the server's env block (see step 2). Same trust model as any other API key/secret configured for an MCP server in mcp.json (local file, not committed to git).

  3. Desktop notification (last resort) — the server falls back to asking via a system notification (with a plain terminal prompt as a further fallback), but that requires a human to respond within ~30s of every tool call that needs the database, so it's not recommended for normal use.

2. Add the server to your MCP client config

Running the package with no arguments starts the MCP server itself (stdio transport) — that's what your MCP client's config actually invokes:

{
  "mcpServers": {
    "hilan": {
      "command": "npx",
      "args": ["-y", "hilan-mcp"]
    }
  }
}

If you only ever use this for one employer, you can set a default tenant in the server's env block. Only the first of these that's set is used, in this order — COMPANY_URLCOMPANY_TENANTCOMPANY_CODE:

{
  "mcpServers": {
    "hilan": {
      "command": "npx",
      "args": ["-y", "hilan-mcp"],
      "env": {
        "COMPANY_TENANT": "amdocs",
        "HILAN_DB_KEY": "the-encryption-key-you-set-during-ingest-creds",
        "NODE_EXTRA_CA_CERTS": "/path/to/your-corporate-ca-bundle.pem"
      }
    }
  }
}

HILAN_DB_KEY is only needed if you didn't run npx hilan-mcp setup-key (see step 1) — the OS credential store takes priority when both are present. NODE_EXTRA_CA_CERTS is only needed on networks with a TLS-intercepting corporate proxy (see Reliability notes) — omit it otherwise.

Env var

Example

Notes

COMPANY_URL

https://amdocs.net.hilan.co.il

Highest priority.

COMPANY_TENANT

amdocs

Bare subdomain. Used only if COMPANY_URL isn't set.

COMPANY_CODE

5227

Numeric org code. Used only if neither above is set — requires an extra lookup round-trip.

This same fallback also applies to npx hilan-mcp ingest-creds--tenant is optional if one of these env vars is set. An explicit tenant argument (or --tenant flag) always overrides the env vars.

Use "command": "node", "args": ["/absolute/path/to/hilan-mcp/dist/cli/index.js"] (after npm install && npm run build in that clone) instead of the npx form above.

3. Use it

Ask your assistant things like "sync my last 3 payslips from Hilan", "download my Form 106 for 2025", or "how much net/gross did I earn in June 2026?" (answered instantly from the local database via the query tool, no network round-trip, once that month has been synced at least once) — see the full tool list below.

For AI agents (e.g. Claude) setting this up on a user's behalf

If a user asks you to set up hilan-mcp for them:

  1. You must not run ingest-creds/setup/setup-key yourself via a shell tool — they prompt for a password and/or an encryption key interactively, and your shell tool's transcript could capture what the user types. Tell the user to open their own terminal and run npx hilan-mcp setup --tenant <their-org-code-or-subdomain> themselves, then (recommended) npx hilan-mcp setup-key. Check their npm --version first: on npm 12+ they also need step 0 or the database will fail to open later, in a way that doesn't look related to installation.

  2. Once that's done, you can safely add the MCP server entry to the client's config file (the JSON blocks above) — that part has no secrets in it as long as the user used setup-key (OS credential store) rather than the HILAN_DB_KEY env var fallback.

  3. After the config is added, the user (or their client) needs to reload/ restart the MCP connection for the new tools to appear.

  4. Don't enable HILAN_ENABLE_DEBUG_TOOLS unless the user explicitly asks for the raw .asmx/PDF exploration tools — they're an intentional escape hatch (see Security model), not needed for normal use.

  5. If a tool response includes an _updateNotice field, tell the user and ask if they'd like to update; if they decline, call dismissUpdateNotice with that version (see MCP tools).

MCP tools

Tool

Summary

listTenants

List configured tenants — no secrets.

syncPayslips

Fetch structured payslip data + PDFs for the last N months.

resyncPayslipMonth

Re-fetch one specific month, overwriting what's stored.

syncForm106

Download the Form 106 PDF for a given year.

downloadCombinedPayslipsPdf

One PDF covering a whole month range.

getSalaryTrends

Yearly averages, YoY %, CAGR, and notable raises — computed locally.

listTables / describeTable

Inspect the queryable local schema.

query

Run read-only SQL against local payslip/Form106 data.

getPersonalDetails

Live lookup of personal details (not persisted).

dismissUpdateNotice

Suppress a specific version's update notice.

debugCallAsmx / debugDownloadPdf

Raw API exploration — off by default.

listTenants()

Configured tenants (subdomain, capability, whether login has succeeded before) — no secrets.

syncPayslips(tenant?, monthsBack?, skipPdf?)

Logs in (reusing a saved session if it still works), fetches structured Bruto/Neto/salary-parts data for the last N months (default 3), and downloads each payslip PDF. Set skipPdf: true for a much faster numbers-only sync (e.g. "what did I earn this year"). tenant is optional if COMPANY_URL/COMPANY_TENANT/COMPANY_CODE is set. The tenant's own archive length caps how far back this can actually go — no need to guess a start date.

resyncPayslipMonth(tenant?, period, skipPdf?)

Re-fetches one specific month (e.g. "10_2019" or "10/2019"), overwriting whatever's stored. Use this instead of re-running syncPayslips over the whole history just to retry one bad/truncated PDF or to answer a one-off "how much did I make in month X" question.

syncForm106(tenant?, year?)

Logs in and downloads the Form 106 PDF for a given year (or the tenant's default year). Same tenant fallback as above.

downloadCombinedPayslipsPdf(tenant?, fromMonth, toMonth, destDir?)

Downloads one PDF covering a whole month range (e.g. all of 2015–2024) instead of one file per month. Automatically splits into multiple files if the range would otherwise exceed the server's URL length limit (see Reliability notes) — practical ceiling is roughly 10–15 years per chunk.

Computes salary growth trends from locally-synced payslips only — no live login, no network call. Returns yearly average Bruto/Neto, year-over-year % change between adjacent years, CAGR between the first and last full (12-month) calendar year, overall growth (first vs. last synced month), and "notable jumps" (≥10% YoY change in Bruto). Optional fromYear/toYear scope the calendar years considered. Prefer this over hand-rolling aggregation with query — grouping/sorting by plain period text gets cross-year chronology wrong (e.g. "01_2011" sorts before "02_2010"); this tool sorts by actual calendar month internally.

listTables() / describeTable(table)

Lists queryable tables (payslips, form106 only) and their columns/indexes.

query(sql)

SELECT-only SQL against payslips/form106. credentials, sessions, and tenants are hard-blocked — see Security model. Good for quick questions like "how much net/gross did I earn in June 2026" without touching the network at all.

getPersonalDetails(tenant?)

Logs in and returns personal details (name, national ID, birthdate, address, phone, email, work start date, job type). Live lookup only — not persisted to the local database.

dismissUpdateNotice(version)

Call this if the user declines an update you offered them (see below), so that exact version isn't mentioned again.

debugCallAsmx(tenant?, servicePath, body?) / debugDownloadPdf(tenant?, relativeUrl, fileName)

Debug/exploration only, disabled by default — raw pass-through to any .asmx endpoint, or download of an arbitrary relative PDF URL, on a logged-in session. Requires HILAN_ENABLE_DEBUG_TOOLS=1 in the server's env block; not registered otherwise. Filenames are sanitized (no path traversal) and URLs are restricted to the tenant's own origin (no SSRF).

Update notifications: this server has no UI of its own, so update checks piggyback on whatever tool the agent happens to call next. At most once a day, a successful tool response may include an extra _updateNotice field with a message like "A new hilan-mcp version is available: 0.1.0 -> 0.2.0..." — if you're the AI agent reading this, tell the user and ask if they'd like to update; if they say no, call dismissUpdateNotice with that version so it isn't raised again (a newer version will still be announced later). The check itself hits the npm registry with a 3s timeout and silently no-ops if it's unreachable (e.g. offline, corporate proxy) — it never fails a tool call.

Concurrency note: every tool call for a given tenant is automatically queued and run one-at-a-time internally (see TenantService.runExclusive) — Hilan's site (and/or the network path to it) doesn't handle concurrent requests from one session well and everything times out otherwise. You don't need to serialize calls yourself; different tenants still run fully in parallel.

Scope (v1)

  • ✅ Payslips (list, structured Bruto/Neto/parts, PDF)

  • ✅ Form 106 (PDF, per year)

  • ⛔ General file archive, Form 101 — not built (v1.1+)

  • ⛔ One-time-code / 2FA login — tenants that require it return a clear "unsupported" error instead of hanging

Tenants whose internal API response doesn't match the structured shape seen on the reference tenant (Amdocs) are marked pdf_only: payslip syncs still work and still save a PDF, just without the parsed Bruto/Neto numbers.

Reliability notes (learned from a real end-to-end run)

  • Corporate TLS-intercepting proxies (e.g. Amdocs's network) break Playwright's Node-side context.request for the internal API/PDF calls with self-signed certificate in certificate chain. Set NODE_EXTRA_CA_CERTS to your organization's exported CA bundle in the server's env block if you hit this.

  • Direct PDF download URLs are relative to /Hilannetv2, not the domain root — a URL returned by the JSON API like PersonalFile/PdfPaySlip.aspx/... actually lives at <tenant>/Hilannetv2/PersonalFile/PdfPaySlip.aspx/.... Confirmed via a live browser network capture.

  • PDF downloads go through an in-page fetch() (same-origin, raw URL) rather than context.request, which silently re-encodes literal / in query strings to %2F and gets 404'd by some endpoints.

  • The same corporate proxy occasionally truncates a PDF response mid-stream (observed: suspiciously round 32768-byte cutoffs) without the fetch itself erroring. downloadPdf checks the whole buffer for the standard %%EOF PDF trailer (not just the tail — some genuine Hilan PDFs have tens/hundreds of KB of trailing null-byte padding after a valid %%EOF) and retries up to 3 times before giving up.

  • Combined multi-month PDFs (PaySlipApiapi.asmx/GetMultiplePaySlipData, one file covering a date range instead of one per month) hit a hard HTTP 404 once the URL exceeds ~2048 characters — that's IIS's default requestFiltering maxQueryString limit, not a Hilan-specific cap (each month adds ~11 chars to the URL). Verified working at 120 months (10 years, ~1.4KB URL); verified failing at 194 months (~16 years, 2.2KB URL) — so a ~15-year request is the realistic practical ceiling per combined PDF. Not an issue for per-month syncing (syncPayslips), which never builds one huge URL.

  • A tenant's regular login page can unconditionally show a "log in with a one-time code" button/link even when normal username+password login is fully supported and working — don't treat that text alone as proof OTP is required. Only genuinely new OTP-input fields (or navigating to an OTP-specific route) after a failed login count as OTP being required.

Security model

  • The whole SQLite database (~/Library/Application Support/HilanMcp/hilan.db on macOS, XDG/AppData equivalents elsewhere) is encrypted at rest via SQLCipher (better-sqlite3-multiple-ciphers), keyed by a passphrase you choose that is never persisted to disk. PDFs live alongside it under .../HilanMcp/pdfs/<tenant>/, and rolling log files under .../HilanMcp/logs/ (redacted — see below). App-data, PDF, and log directories are created with 0700 permissions; the DB and PDF files themselves with 0600.

  • credentials (your login fields) and sessions (saved browser cookies) are ordinary tables inside that encrypted database, but they are never reachable through the query/listTables/describeTable tools — those are hard-allowlisted to payslips and form106 only, validated via a full SQL AST parse (not a regex) so JOINs, subqueries, and quoted identifiers can't be used to sneak past the allowlist (see src/utils/sqlValidation.ts and src/tests/sqlValidation.test.ts).

  • Cookies and auth headers are redacted from log files and from any error message a tool call returns, so a Playwright error can't leak your session into your chat history (see src/utils/redact.ts).

  • Credential entry (ingest-creds) must be run directly by you in your own terminal — never through an assistant's shell tool, whose transcript could capture what you typed.

  • debugCallAsmx is an intentional escape hatch: it lets a logged-in session call any .asmx endpoint with any body, bypassing the curated tools above. It was added for API exploration during development and is one-employee-scoped (same session, same permissions you already have on the site) — it can't reach other employees' data or other tenants — but it could in principle call a write endpoint (Hilan generally gates writes behind approval flows, but this hasn't been audited). Off by default (HILAN_ENABLE_DEBUG_TOOLS); treat it like query's SQL escape hatch — fine for an AI assistant you trust to explore with, not something to expose to untrusted input.

Development

Clone this repo to work on the code itself (not needed just to use the server — see Setup above for that):

npm install
npm run typecheck
npm test                 # unit tests (SQL allowlist, path-traversal, redaction, update checks, ...)
npm run build            # compile TypeScript -> dist/
npm run start:mcp        # run the server directly from source (stdio transport)
npm run setup            # local equivalent of `npx hilan-mcp setup`
npm run ingest-creds     # register a tenant + credentials (interactive, run yourself)
npm run setup-key        # store the DB encryption key in your OS credential store (interactive, run yourself)

npm publish ships only dist/, README.md, and LICENSE (see the files field in package.json) — source, tests, and local research artifacts are excluded. prepublishOnly runs typecheck + tests + build first, so a broken build can't be published. The published bin entry (dist/cli/index.js) is what npx hilan-mcp and npx hilan-mcp <subcommand> both invoke.

License

MIT

Available Tools

10 tools
describeTableA

Get columns and indexes for a table (payslips or form106 only)

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYesTable to describe

TDQS

A4/5.0
Behavior3/5

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

With no annotations provided, the description alone must convey behavioral traits. The verb 'Get' implies a read-only operation with no side effects, but the description does not explicitly state safety (e.g., no data modification) or clarify the response format. It is adequate but lacks richer behavioral disclosure.

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 a single, well-formed sentence that front-loads the action and includes a necessary scope restriction. Every word earns its place; there is no redundancy or unnecessary detail.

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 tool is simple (one parameter, no output schema, no annotations). The description covers the core purpose and allowed inputs. Although it does not describe the return value format, the phrase 'columns and indexes' already implies the output structure. For this low complexity, the description is sufficiently 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?

The input schema already fully describes the single parameter 'table' with an enum and description. The tool description merely repeats the allowed values ('payslips or form106 only'), adding no additional semantic meaning beyond the schema. With 100% schema coverage, the baseline of 3 applies.

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: 'Get columns and indexes for a table'. The verb 'Get' is specific, the resource (columns and indexes) is well-defined, and the scope restriction ('payslips or form106 only') distinguishes it from sibling tools that perform sync, download, or query operations.

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

Usage Guidelines4/5

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

The description provides a clear constraint on when the tool is applicable: 'payslips or form106 only'. This tells the agent not to use it for other tables. However, it does not explicitly name alternative tools for those cases (e.g., listTables) or state when to prefer them, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dismissUpdateNoticeA

Call this after the user declines an update offered via an "_updateNotice" field on a previous tool response, passing that same version string, so hilan-mcp stops mentioning that specific version. It will still notify about a newer version later.

ParametersJSON Schema
NameRequiredDescriptionDefault
versionYesThe version string from the _updateNotice you want to dismiss, e.g. "0.2.0"

TDQS

A4.3/5.0
Behavior4/5

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

Without annotations, the description carries the burden of behavioral disclosure. It explains the effect of the call (stops mentioning the specified version) and notes it will still mention newer versions. This is sufficient for a simple dismissal action, though it doesn't detail side effects or return values.

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?

Two concise sentences, front-loaded with the action and context. Every sentence earns its place, with no fluff or repetition.

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

Completeness5/5

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

The tool is extremely simple: one parameter, no output schema. The description fully explains when to use it, what it does, and the expected outcome. There's no meaningful gap in context for an agent to invoke it correctly.

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 coverage is 100%, so the baseline is 3. The tool description reinforces that the version must be the same as the one from the _updateNotice, but the schema already provides the full description of the parameter. No significant additional semantic detail is added.

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: dismiss an update notice by passing the same version string from a previous _updateNotice. It is specific and distinguishes itself from sibling tools (syncPayslips, query, etc.) which are unrelated to update notices.

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

Usage Guidelines4/5

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

It explicitly says when to call it: after the user declines an update offered via an _updateNotice field. It also explains the result (stops mentioning that version) and sets expectations about future notifications, but doesn't explicitly discuss when not to use it or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

downloadCombinedPayslipsPdfA

Downloads ONE PDF covering every payslip in a date range (instead of one file per month) — handy for printing/sharing a multi-year span at once. Automatically splits into multiple files for very long ranges (Hilan's combined-PDF endpoint has a practical ceiling of roughly 12-15 years per file due to a URL-length limit on their end).

ParametersJSON Schema
NameRequiredDescriptionDefault
tenantNoTenant subdomain, e.g. "amdocs". Optional if this server has COMPANY_URL / COMPANY_TENANT / COMPANY_CODE set in its env
toMonthYesEnd of the range (inclusive), "MM_YYYY" or "MM/YYYY", e.g. "12/2025"
fromMonthYesStart of the range (inclusive), "MM_YYYY" or "MM/YYYY", e.g. "01/2020"

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description discloses the key behavioral trait: automatic splitting for long ranges due to a URL-length ceiling, including the approximate threshold (12-15 years). This adds value beyond the schema, though it doesn't cover failure modes or authentication requirements.

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 long: the first states the core purpose, the second adds a crucial caveat. It is well-structured and free of filler.

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?

Given the tool's simplicity (3 parameters, no output schema), the description covers the main behavior and the split caveat. It doesn't explicitly state the return format, but 'Downloads ONE PDF' implies a file response, and the sibling tool context doesn't require more.

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 input schema already provides descriptions for all three parameters (fromMonth, toMonth, tenant) with format examples. The description adds no further parameter-level detail, so the baseline 3 is appropriate.

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 function: downloads one combined PDF for all payslips in a date range, explicitly contrasting with the per-month approach. This distinguishes it from sibling tools like syncPayslips or listTenants by focusing on the combined download use case.

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

Usage Guidelines4/5

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

It provides context for when to use the tool ('handy for printing/sharing a multi-year span at once') and contrasts with per-month downloads. However, it does not explicitly name alternative tools or state when not to use it, though the 'instead of one file per month' hint covers this.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getPersonalDetailsA

Logs in and fetches personal details (name, national ID, birthdate, address, phone, email, work start date, job type). This is a live lookup, not stored in the local database.

ParametersJSON Schema
NameRequiredDescriptionDefault
tenantNoTenant subdomain, e.g. "amdocs". Optional if this server has COMPANY_URL / COMPANY_TENANT / COMPANY_CODE set in its env

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the full burden. It discloses the login side effect and the live nature of the lookup, which adds behavioral context. It does not detail authentication requirements or session implications, but for a simple fetch operation this is reasonably transparent.

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?

Two efficient sentences that front-load the verb and resource, list the retrieved fields, and provide a key behavioral note. No redundant or filler content.

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 tool is simple (1 optional param, no output schema). The description covers what it does and a key contextual detail ('live lookup'). It lacks return format details, but given the low complexity and field enumeration, it is sufficiently complete for an agent to select and invoke the tool.

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 schema has 100% parameter description coverage, including the 'tenant' field's purpose. The description adds no new parameter semantics, so the baseline of 3 applies as per the rubric.

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 uses a specific verb ('fetches') and clearly identifies the resource ('personal details') with an enumerated list of fields. It distinguishes itself from sibling tools like syncPayslips and query, which deal with other data or local database operations.

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

Usage Guidelines4/5

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

The statement 'This is a live lookup, not stored in the local database' provides clear context for when to use this tool (when fresh data is needed) and implicitly contrasts with local DB tools like query. However, it does not explicitly name alternative tools or provide exclusion scenarios.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listTablesA

List queryable tables (payslips, form106 — credentials/sessions are never exposed here)

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

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

Although no annotations are provided, the description discloses a key behavioral guarantee: credentials/sessions are never exposed. It also implies a read-only listing operation, which is sufficient for a simple list tool.

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?

A single sentence that is front-loaded with the main action, followed by a necessary caveat. No wasted 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?

For a simple list operation with no parameters and no output schema, the description adequately communicates scope and exclusions. It could mention output format, but the simplicity of the tool makes this sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The description adds value by clarifying what is listed without needing to explain parameters.

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 uses a specific verb ('List') and resource ('queryable tables'), names concrete examples (payslips, form106), and explicitly excludes credentials/sessions, which distinguishes it from sibling tools that might expose sensitive data.

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?

It implies this tool is for discovering available tables before querying, but it does not explicitly state when to use it over alternatives like describeTable or query. The context is clear but not fully prescriptive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listTenantsA

List configured Hilan tenants (no secrets returned)

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior3/5

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

With no annotations, the description carries the full burden of disclosure. It explicitly states 'no secrets returned,' which is a useful safety guarantee. However, it does not mention authentication requirements, whether the list is cached, or any potential side effects.

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?

A single, efficient sentence that front-loads the action and includes a meaningful safety note, with no wasted 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?

Given the tool's simplicity—no parameters, no output schema—the description adequately conveys what the tool does and its key behavioral constraint. It could be more explicit about the structure of the returned tenant list, but that is not critical for this simple list operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the description naturally has nothing to add about parameter semantics. Per the rubric, 0 parameters earns a baseline 4, and no further elaboration is needed.

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 uses a specific verb ('List') and a clear resource ('configured Hilan tenants'), making its purpose immediately clear and distinct from sibling tools like syncPayslips or query.

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 relative to alternatives, and there is no mention of prerequisites or context. For example, it doesn't say whether tenant IDs obtained here are needed as inputs for other Hilan tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

queryA

Execute a SELECT-only SQL query against payslips/form106 (allowlisted; credentials/sessions/tenants are never reachable)

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYesSQL SELECT query, e.g. "SELECT * FROM payslips ORDER BY period DESC"

TDQS

A4.5/5.0
Behavior4/5

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

Since no annotations are provided, the description carries the full burden of behavioral disclosure. It states the tool is SELECT-only and that credentials/sessions/tenants are never reachable, providing important safety and scope constraints. It lacks details like return format, but this is sufficient for a simple query tool.

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 a single, well-structured sentence that front-loads the core action and includes relevant constraints. Every word adds value, with no redundancy.

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

Completeness5/5

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

Given the simplicity of the tool (one parameter, no output schema, no annotations), the description covers all essential aspects: purpose, allowed tables, and safety. It is complete enough for an AI agent to invoke correctly without further clarification.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers the 'sql' parameter with a description and example. The tool description adds extra meaning by specifying allowed tables (payslips/form106) and the SELECT-only constraint, which are not present in the schema.

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 function: executing a SELECT-only SQL query against specific tables (payslips/form106). This distinguishes it from sibling tools like syncPayslips or downloadCombinedPayslipsPdf, which perform different actions.

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

Usage Guidelines4/5

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

The description implies when to use the tool (for read-only SQL queries) and sets boundaries (SELECT-only, only specific tables). While it doesn't explicitly name alternatives or exclusion conditions, the context is clear enough for an AI agent to select it appropriately among siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resyncPayslipMonthA

Re-fetch a single specific month (structured data, and by default the PDF too), overwriting whatever is already stored for it. Use this to retry one bad/truncated PDF, or to quickly check one month's numbers, instead of re-running syncPayslips over the whole history.

ParametersJSON Schema
NameRequiredDescriptionDefault
periodYesThe month to resync, as "MM_YYYY" (matches the stored period key) or "MM/YYYY", e.g. "10_2019" or "10/2019"
tenantNoTenant subdomain, e.g. "amdocs". Optional if this server has COMPANY_URL / COMPANY_TENANT / COMPANY_CODE set in its env
skipPdfNoIf true, only fetch the structured Bruto/Neto/parts data and skip the PDF — fast, no browser download. Default false.

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description discloses the key behavioral trait: overwriting whatever is already stored. It also mentions that the PDF is fetched by default (and can be skipped via skipPdf). It does not mention return values or edge cases, but the critical overwriting behavior is clearly stated.

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 concise sentences: the first states the core action and scope, the second provides use cases and alternatives. No unnecessary words or repetition of schema details.

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?

Given the simple tool with a well-documented schema and no annotations, the description provides sufficient context: purpose, scope, overwriting behavior, and when to use it. The lack of return-value mention is a minor gap since no output schema exists, but the essential information is present.

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 input schema has 100% parameter coverage with detailed descriptions for period, tenant, and skipPdf. The description does not add any new parameter semantics beyond what the schema already provides, so the baseline score of 3 is appropriate.

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 re-fetches a single specific month's payslip data and PDF, overwriting existing stored data. It explicitly names the resource and scope, and distinguishes itself from syncPayslips by mentioning the alternative.

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

Usage Guidelines5/5

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

The description explicitly provides when to use this tool ('to retry one bad/truncated PDF, or to quickly check one month's numbers') and when not to ('instead of re-running syncPayslips over the whole history'), making the use case clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

syncForm106A

Log into a Hilan tenant and download Form 106 (annual tax summary) for a given year, or the default year

ParametersJSON Schema
NameRequiredDescriptionDefault
yearNoTax year, e.g. "2025" (defaults to the tenant's current default year)
tenantNoTenant subdomain, e.g. "amdocs". Optional if this server has COMPANY_URL / COMPANY_TENANT / COMPANY_CODE set in its env

TDQS

A3.7/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions 'log into a Hilan tenant' (a side effect) and 'download' (a read-like action), but the tool name 'syncForm106' suggests a syncing operation that might write data locally. The description does not clarify whether this is read-only, whether it stores data, or what side effects occur. This is a significant transparency gap.

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 a single sentence that front-loads the core action ('Log into a Hilan tenant and download Form 106') and then specifies the variable part (year). It contains no unnecessary words or fluff, earning a perfect score.

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?

Given there is no output schema, the description should ideally explain what the tool returns (e.g., a file path, PDF content, or successful message). It does not mention return value or any post-download behavior. Additionally, the 'sync' aspect is unexplained, leaving uncertainty about whether the tool stores data. The description covers the action but not the full context.

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 input schema already provides full descriptions for both parameters (year and tenant), so schema coverage is 100%. The description adds clarity by mentioning 'for a given year, or the default year', which explains the year parameter's default behavior. No additional parameter semantics are needed beyond that.

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 action: 'download Form 106 (annual tax summary)' from a Hilan tenant for a given year. It specifies the resource (Form 106) and differentiates it from sibling tools like syncPayslips, which handle payslips, making the purpose distinct.

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

Usage Guidelines4/5

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

The description implies when to use this tool: whenever a user needs an annual tax summary (Form 106). It does not explicitly mention alternatives or exclusions, but the context is clear. The sibling tools list shows different purposes, so there is no ambiguity about when this tool is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

syncPayslipsA

Log into a Hilan tenant (using previously ingested credentials) and sync recent payslips (structured Bruto/Neto/parts + PDF)

ParametersJSON Schema
NameRequiredDescriptionDefault
tenantNoTenant subdomain, e.g. "amdocs". Optional if this server has COMPANY_URL / COMPANY_TENANT / COMPANY_CODE set in its env
skipPdfNoIf true, only fetch/store the structured Bruto/Neto/parts data and skip downloading PDFs — much faster for quick numeric questions. Any previously-downloaded PDF for a month is left untouched. Default false.
monthsBackNoHow many recent months to sync (default 3). The tenant itself caps how far back its payslip archive actually goes — this is just a sanity ceiling, not a real limit.

TDQS

A3.9/5.0
Behavior4/5

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

With no annotations, the description carries full burden. It discloses that authentication uses previously ingested credentials, that it syncs both structured data and PDFs, and includes behavioral notes in parameter descriptions (e.g., skipPdf leaves existing PDFs untouched). This goes beyond merely repeating the tool name, though it lacks details on error handling or idempotency.

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 a single well-structured sentence that front-loads the primary action and includes essential context (login, data types). Every word adds value, with no fluff or redundancy.

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?

The tool has 3 parameters, no output schema, and no annotations. The description covers prerequisites and actions but does not mention return values or success/failure behavior. Since there is no output schema, the description should hint at what the agent receives after invocation, which it does not.

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% and each parameter has a detailed description explaining semantics (e.g., tenant optional via env, skipPdf behavior, monthsBack as a sanity ceiling). The tool description itself does not add parameter meaning beyond the schema, so the baseline of 3 applies.

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 a specific action: 'Log into a Hilan tenant... and sync recent payslips', with a clear verb+resource. It distinguishes itself from siblings by specifying syncing recent data (vs resyncPayslipMonth for a specific month or downloadCombinedPayslipsPdf for combined PDF).

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 usage when recent payslip data is needed but does not explicitly mention when not to use it or name alternatives like downloadCombinedPayslipsPdf or resyncPayslipMonth. No exclusions or comparison to sibling tools is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A4/5.0
Disambiguation4/5

Most tools are clearly distinct, but syncPayslips and resyncPayslipMonth could be confused at a glance. Descriptions help disambiguate their scope, and the built-in querying tools (listTables, describeTable, query) are related but serve different purposes.

Naming Consistency4/5

All tool names use camelCase and follow a verb-first pattern (sync, download, get, resync, list, describe, dismiss), but 'query' is a bare verb and 'dismissUpdateNotice' is verbose. Overall consistent, with a few minor deviations.

Tool Count5/5

With 10 tools, the server is well-scoped. Each tool addresses a clear need for Hilan payroll integration, and none seem superfluous.

Completeness4/5

The tool surface covers core workflows: syncing payslips, downloading combined PDFs, retrieving personal details, and querying stored data. Missing operations like updating or deleting payslips are not typical for a read-only integration, but there's no explicit tool for managing credentials or tenants beyond listing them, which is a minor gap.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • F
    license
    D
    quality
    F
    maintenance
    A Model Context Protocol server that allows AI assistants to connect to and manage Israeli bank accounts, fetch transactions, and handle authentication for all major Israeli banks and credit card companies.
    2
    33
  • A
    license
    Not graded
    quality
    B
    maintenance
    An MCP server that enables AI assistants to control a real browser with your existing sessions and extensions, avoiding bot detection and authentication hurdles.
    99
    Apache 2.0

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/udah1/hilan-mcp'

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