Skip to main content
Glama
kumr192

Fusion Holds & Funds Desk MCP

by kumr192

Fusion Holds & Funds Desk MCP

A Model Context Protocol (MCP) server for the Oracle Fusion Cloud ERP holds and funds desk. It answers the question an AP analyst asks a dozen times a day — why is this invoice not paying? — by pulling the invoice, the holds on it, the accounting period status, and the budgetary control result into one place, with the resolution steps and the owning team attached to each hold.

It is read-only. Nothing here releases a hold, opens a period, or reserves funds.

The one rule: funds balances are never invented

This server reports funds statuses and failure reasons. It reports a funds balance only when Oracle Budgetary Control hands one over.

It never estimates a balance, never derives one by arithmetic from invoice amounts, never carries one forward from an earlier call, and never emits a placeholder number that a reader could mistake for a real funds position. When Budgetary Control does not supply a figure, every numeric field comes back null alongside dataAvailability: "unavailable", the reason it is unavailable, and instructions on where to get the real number.

The rule is enforced in code, not just documented. Every balance record passes through sealBalances in src/domain/fundsPolicy.ts, which strips numeric fields unless the record was built directly from a Budgetary Control API response, and get_budgetary_control_impacts re-asserts the invariant before returning. Mock mode drops balances unconditionally, even if a fixture tries to supply them.

Related MCP server: mcp-oraclefusion

Tools

Tool

What it answers

get_invoice

The facts: header, amounts, validation/approval/payment/accounting status, matched purchase orders, lines.

get_invoice_holds

What is holding the invoice, what each hold code means, who owns the fix, whether revalidation clears it, and the steps that do.

get_accounting_period_status

Whether the AP and GL periods allow accounting for a given period or accounting date.

get_budgetary_control_impacts

The funds check result, the control budgets involved, and which lines and distributions failed and why.

A typical run: get_invoice to establish the facts, get_invoice_holds to see what is blocking it, then get_accounting_period_status or get_budgetary_control_impacts depending on which category of hold came back.

Identifying an invoice

Pass invoiceId when you have it. An invoice number is unique only within a supplier and business unit, so add supplierName, supplierNumber, or businessUnit to disambiguate. If more than one invoice still matches, the tool returns an AMBIGUOUS_MATCH error listing the candidates rather than picking one for you.

Result shape

Every tool returns a readable text summary plus structuredContent validated against a published output schema:

  • meta — which tool ran, whether it was mock or live, the source resource, and the retrieval timestamp.

  • The payload — invoice, holds, periods, or budgetary control result.

  • Guidance — nextSteps or recommendedActions, prioritised, with the owning team named.

  • disclaimers — including the balance rule above, and a mock-mode warning when applicable.

Failures come back as MCP tool errors (isError: true) carrying a machine-readable code (NOT_FOUND, AMBIGUOUS_MATCH, AUTH_FAILED, RESOURCE_UNAVAILABLE, TIMEOUT, RATE_LIMITED, UPSTREAM_ERROR, INVALID_ARGUMENT, CONFIG_INVALID) and remediation steps — never a fabricated result.

Install and build

Requires Node.js 18.17 or newer (Node 20+ recommended).

git clone https://github.com/kumr192/fusion-holds-funds-desk-mcp.git
cd fusion-holds-funds-desk-mcp
npm install
npm run build

Then verify the build:

npm test          # unit and integration tests
npm run smoke     # starts the built server over stdio and calls every tool
npm run doctor    # prints the resolved configuration; probes the pod in live mode

Running on Windows

The steps below are what to run on a Windows machine from PowerShell. Everything is cross-platform — no WSL, no build tools, no Python.

1. Install Node.js. Get the current LTS from nodejs.org, then confirm it in a new PowerShell window:

node --version
npm --version

2. Clone and build.

cd $HOME\code
git clone https://github.com/kumr192/fusion-holds-funds-desk-mcp.git
cd fusion-holds-funds-desk-mcp
npm install
npm run build

npm install && npm run build is the whole setup. The build writes dist\index.js, which is the file the MCP client launches.

3. Confirm it works before wiring it into a client.

npm test
npm run smoke

npm run smoke starts the server exactly as an MCP client would, calls all four tools, and checks that no funds balance leaks out of mock mode. All checks should pass.

4. Note the absolute path to dist\index.js.

(Resolve-Path .\dist\index.js).Path

5. Add it to mcp.json. Use the path from the previous step. In JSON, backslashes must be doubled (\\), or you can use forward slashes.

For Cursor, the file is %USERPROFILE%\.cursor\mcp.json (or .cursor\mcp.json inside a project, for a project-scoped server). For Claude Desktop it is %APPDATA%\Claude\claude_desktop_config.json. Both use the same mcpServers shape:

{
  "mcpServers": {
    "fusion-holds-funds-desk": {
      "command": "node",
      "args": ["C:\\Users\\shiv\\code\\fusion-holds-funds-desk-mcp\\dist\\index.js"],
      "env": {
        "FUSION_MODE": "mock"
      }
    }
  }
}

Ready-to-edit copies are in examples/mcp.mock.json and examples/mcp.live.json.

6. Restart the MCP client so it picks up the change. The server should appear with four tools.

7. Try it. Ask: "Why is invoice INV-1001 on hold?" or "Is the GL period open for FEB-26?"

Switching to live. Change the env block to point at your pod:

{
  "mcpServers": {
    "fusion-holds-funds-desk": {
      "command": "node",
      "args": ["C:\\Users\\shiv\\code\\fusion-holds-funds-desk-mcp\\dist\\index.js"],
      "env": {
        "FUSION_MODE": "live",
        "FUSION_BASE_URL": "https://your-pod.fa.us2.oraclecloud.com",
        "FUSION_USERNAME": "AP_INTEGRATION_USER",
        "FUSION_PASSWORD": "...",
        "FUSION_DEFAULT_LEDGER": "US Primary Ledger",
        "FUSION_DEFAULT_BUSINESS_UNIT": "US1 Business Unit"
      }
    }
  }
}

Before restarting the client, check the credentials and resource paths from the terminal — npm run doctor validates the configuration and probes the invoices resource, so a bad password or a wrong path surfaces as a clear message instead of a failed tool call:

$env:FUSION_MODE="live"
$env:FUSION_BASE_URL="https://your-pod.fa.us2.oraclecloud.com"
$env:FUSION_USERNAME="AP_INTEGRATION_USER"
$env:FUSION_PASSWORD="..."
npm run doctor

Windows troubleshooting

  • npm : File ... npm.ps1 cannot be loaded — PowerShell's execution policy is blocking npm. Run Set-ExecutionPolicy -Scope CurrentUser RemoteSigned in an elevated window, or use npm.cmd instead.

  • Client shows the server as failed — the path in args is usually the cause. It must be absolute, must point at dist\index.js (not src), and backslashes must be doubled in JSON. Confirm the file exists with Test-Path C:\...\dist\index.js.

  • node not recognised — open a new terminal after installing Node so PATH is refreshed, or use the full path to node.exe as command.

  • Works in the terminal, not in the client — the client does not inherit your shell environment. Every variable the server needs must be in the env block of mcp.json.

Mock mode vs live mode

Mock mode (FUSION_MODE=mock, the default) serves deterministic fixtures: no pod, no credentials, no network. The fixture set covers a matching hold (INV-1001), a funds hold with an invalid account (2026-0234), a clean paid invoice in a closed period (AUR-55120), a manual hold plus a tax variance (TRI-2026-88), and an invoice dated into a period that was never opened (VE-4471). Mock results are labelled as such in meta.mode and in the disclaimers, and mock mode never returns funds balances.

Live mode (FUSION_MODE=live) calls Oracle Fusion Cloud ERP REST with basic auth or a bearer token, with a configurable timeout and bounded retries on 429 and 5xx responses. Fusion resource names vary by release and by which offerings are enabled, so every resource path is overridable — see .env.example. When a resource is missing or forbidden, the affected data is reported as unavailable with the HTTP diagnostic; no value is assumed in its place.

Configuration

All configuration is environment variables; .env.example documents every one. The essentials:

Variable

Default

Purpose

FUSION_MODE

mock

mock or live.

FUSION_BASE_URL

Pod origin. Required in live mode.

FUSION_USERNAME / FUSION_PASSWORD

Basic auth for the integration user.

FUSION_TOKEN

Bearer token; takes precedence over basic auth.

FUSION_DEFAULT_LEDGER

Ledger used when a call omits ledgerName.

FUSION_DEFAULT_BUSINESS_UNIT

Business unit used when a call omits businessUnit.

FUSION_BC_BALANCES_ENABLED

false

Opt in to querying Budgetary Control balances. Off means balances are always reported as unavailable.

FUSION_TIMEOUT_MS

30000

Per-request timeout.

FUSION_MAX_RETRIES

2

Retries for 429 and 5xx responses.

LOG_LEVEL

info

debug, info, warn, error, or silent. Logs go to stderr.

Secrets are never logged: describeConfig reports the auth kind and the username, never the password or token.

Development

src/
  index.ts              stdio entrypoint
  server.ts             MCP server assembly and tool registration
  config.ts             environment parsing and validation
  errors.ts             error taxonomy with remediation
  logger.ts             stderr JSON logging
  domain/
    fundsPolicy.ts      the never-invent-balances rule, enforced
    holdCatalog.ts      hold code reference: meaning, owner, resolution steps
    format.ts           text summary helpers
  fusion/
    types.ts            domain model shared by both clients
    httpClient.ts       live Oracle Fusion REST client
    mockClient.ts       fixture-backed client
    createClient.ts     mode-based factory
  fixtures/desk.ts      deterministic fixtures
  tools/                the four tools, their schemas, and shared plumbing
tests/                  vitest suite
scripts/                clean, doctor, smoke

Script

Purpose

npm run build

Compile TypeScript to dist/.

npm test

Run the vitest suite.

npm run test:coverage

Run tests with coverage.

npm run typecheck

Typecheck sources and tests without emitting.

npm run check

Typecheck, then test.

npm run smoke

Start the built server over stdio and exercise every tool.

npm run doctor

Print the resolved configuration; probe the pod in live mode.

npm run clean

Remove dist/ and coverage/.

The test suite covers configuration parsing, the hold catalog, both clients (the live one against a stubbed fetch), all four tools, and the full MCP handshake over an in-memory transport. Several tests exist purely to pin the balance rule: fixtures carry no amounts, mock mode strips injected balances, the seal drops unsourced numbers, and no numeric balance survives a mock-mode tool call.

License

MIT — see LICENSE.

Available Tools

4 tools
get_accounting_period_statusGet accounting period statusA
Read-onlyIdempotent

Report Oracle Fusion accounting period status for Payables (AP) and General Ledger (GL): Open, Closed, Permanently Closed, Never Opened, or Future Enterable. Query by period name, or by accountingDate to resolve the period that contains an invoice's accounting date. Use this when an invoice will not account, when an accounting date is rejected, or before asking for a period to be reopened. If a period status cannot be read it is reported as unavailable with the reason; a status is never assumed.

ParametersJSON Schema
NameRequiredDescriptionDefault
modulesNoWhich modules to report. Defaults to both AP and GL.
ledgerNameNoLedger name, e.g. 'US Primary Ledger'. Falls back to FUSION_DEFAULT_LEDGER when omitted.
periodNameNoAccounting period name, e.g. 'MAR-26'.
businessUnitNoBusiness unit, used for Payables period status. Falls back to FUSION_DEFAULT_BUSINESS_UNIT.
accountingDateNoResolve the period that contains this date. Use instead of periodName when you have an invoice date.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaYes
queryYes
periodsYes
summaryYes
nextStepsYes
assessmentYes
disclaimersYes
openPeriodsYes
unavailableYes
dataAvailabilityYesWhether the reported data is complete, partially available, or not available at all.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the description adds meaningful extras: unreadable statuses are returned as 'unavailable' with a reason and 'a status is never assumed'. This error-handling contract is genuinely useful context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with purpose then usage then behavior, with no filler. Slightly dense sentence one, but every clause carries information.

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?

With an output schema and full annotations available, the description needn't explain return values, and it covers the one non-obvious behavioral case (unavailable status). Fallback defaults are noted, though the description could say more about how AP vs GL statuses relate when both are requested.

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%, so the schema already documents modules, ledgerName, periodName, businessUnit, and accountingDate, including defaults and fallbacks. The description restates the periodName-vs-accountingDate choice but adds no syntax or precedence detail beyond what the schema says, so the 3 baseline 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?

States a specific verb and resource (report Oracle Fusion accounting period status for AP and GL) and enumerates the exact status values returned. It also distinguishes itself from siblings like get_invoice and get_invoice_holds by describing period-level resolution rather than invoice-level data.

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?

Gives explicit trigger conditions: when an invoice will not account, when an accounting date is rejected, or before asking for a period to be reopened. It does not name a competing alternative tool or state when *not* to use it, so it falls short of the 5-level bar for routing guidance.

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

get_budgetary_control_impactsGet budgetary control impactsA
Read-onlyIdempotent

Explain the budgetary control impact on an Oracle Fusion Payables invoice: the funds check / funds reservation status, which control budgets are involved, and which lines and distributions failed and why. Use when an invoice carries an Insufficient Funds or Funds Check Failure hold, or before promising a payment date on a budget-controlled invoice. Important: this tool never estimates or derives funds balances. Budget and funds-available figures are reported only when Oracle Budgetary Control returns them; otherwise they are null with the reason they are unavailable and guidance on where to obtain them.

ParametersJSON Schema
NameRequiredDescriptionDefault
invoiceIdNoFusion InvoiceId. The most precise identifier; use it when you have it.
businessUnitNoBusiness unit that owns the invoice.
supplierNameNoSupplier name, used to disambiguate an invoice number.
invoiceNumberNoSupplier invoice number. Unique only within a supplier and business unit.
supplierNumberNoSupplier number, used to disambiguate an invoice number.
includeBalancesNoAttempt to retrieve funds balances from the Budgetary Control balances resource. Defaults to false. Balances are returned only if Budgetary Control supplies them; they are never estimated.
includeRelatedHoldsNoInclude the invoice holds caused by budgetary control. Defaults to true.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaYes
impactYes
invoiceYes
summaryYes
disclaimersYes
relatedHoldsYes
fundsBalancesYes
budgetaryControlYes
recommendedActionsYes

TDQS

A4.4/5.0
Behavior5/5

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

Annotations cover the safety profile (readOnly, idempotent, non-destructive, open world), and the description adds a genuinely distinctive behavioral constraint: it never estimates or derives balances, returning null plus a reason and guidance when Oracle Budgetary Control does not supply figures. This is meaningful context beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then usage trigger, then the Important caveat in priority order. Every sentence contributes, though the closing caveat is somewhat lengthy and could be tightened without losing meaning.

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?

An output schema exists, so return values need no explanation. Purpose, trigger conditions, and the key limitation on balance reporting are all covered, leaving nothing an agent needs in order 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% and the schema already documents the identifier options and both boolean toggles, including that balances are never estimated. The description adds no syntax, format, or precedence detail beyond what the schema states, so baseline 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?

States a specific verb and resource (explain budgetary control impact on an Oracle Fusion Payables invoice) and enumerates exactly what is reported: funds check/reservation status, control budgets involved, and which lines/distributions failed and why. This is well differentiated from siblings like get_invoice_holds, which would only surface the hold without the funds-check reasoning.

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?

Gives concrete triggering conditions: when an invoice carries an Insufficient Funds or Funds Check Failure hold, or before promising a payment date on a budget-controlled invoice. It does not explicitly name an alternative tool or state when not to use it, so it stops 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.

get_invoiceGet invoiceA
Read-onlyIdempotent

Retrieve a single Oracle Fusion Payables invoice: header, amounts, validation/approval/payment status, matched purchase orders, and lines. Identify the invoice by invoiceId, or by invoiceNumber plus supplierName/supplierNumber/businessUnit when the number alone is ambiguous. Use this first to establish the facts of an invoice, then call get_invoice_holds, get_accounting_period_status, or get_budgetary_control_impacts for the reason it is stuck.

ParametersJSON Schema
NameRequiredDescriptionDefault
invoiceIdNoFusion InvoiceId. The most precise identifier; use it when you have it.
businessUnitNoBusiness unit that owns the invoice.
includeHoldsNoAlso fetch active holds so the summary lists hold codes. Defaults to false; use get_invoice_holds for full hold guidance.
includeLinesNoInclude invoice lines in the result. Defaults to true.
supplierNameNoSupplier name, used to disambiguate an invoice number.
invoiceNumberNoSupplier invoice number. Unique only within a supplier and business unit.
supplierNumberNoSupplier number, used to disambiguate an invoice number.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaYes
invoiceYes
summaryYes
nextStepsYes
disclaimersYes
holdSnapshotYes

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds real behavioral context beyond that: the ambiguity of invoiceNumber across supplier/business unit, the breadth of returned data, and the intended first-step role in a diagnostic sequence. It stops short of noting pagination or permission requirements, so not a full 5.

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 sentences, zero filler, and the retrieval scope plus identification strategy are front-loaded before the downstream-tool routing. Every clause carries actionable information.

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?

For a read-only lookup with full schema coverage and an output schema covering return structure, the description supplies everything an agent needs: what it fetches, how to select the record, and where to go next. Nothing material is missing.

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?

Schema coverage is 100%, so the baseline is 3, but the description goes further by spelling out the combination rule (invoiceNumber requires supplierName/supplierNumber/businessUnit) rather than leaving the agent to assemble the individual field hints. That said, it does not explain includeHolds/includeLines defaults, which live only 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?

States a specific verb and resource ("Retrieve a single Oracle Fusion Payables invoice") and enumerates exactly what comes back: header, amounts, validation/approval/payment status, matched POs, and lines. An agent can immediately distinguish this from get_invoice_holds, which only surfaces hold detail.

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?

Explicitly states how to identify the invoice (invoiceId, or invoiceNumber plus supplierName/supplierNumber/businessUnit when the number is ambiguous) and names the exact sequencing: use this first to establish facts, then call get_invoice_holds, get_accounting_period_status, or get_budgetary_control_impacts for the root cause. All three siblings are routed to by name and purpose.

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

get_invoice_holdsGet invoice holdsA
Read-onlyIdempotent

List the holds on an Oracle Fusion Payables invoice and explain each one: what the hold code means, which team owns the fix, whether revalidation can release it, and the steps that clear it. Returns prioritised recommended actions and flags whether payment or accounting is blocked. Use after get_invoice when an invoice is not paying or not accounting.

ParametersJSON Schema
NameRequiredDescriptionDefault
holdCodeNoFilter to a single hold code, e.g. "Qty Rec" or "Insufficient Funds".
invoiceIdNoFusion InvoiceId. The most precise identifier; use it when you have it.
businessUnitNoBusiness unit that owns the invoice.
supplierNameNoSupplier name, used to disambiguate an invoice number.
invoiceNumberNoSupplier invoice number. Unique only within a supplier and business unit.
supplierNumberNoSupplier number, used to disambiguate an invoice number.
includeReleasedNoInclude holds that have already been released, for history. Defaults to false.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaYes
holdsYes
countsYes
invoiceYes
summaryYes
blockingYes
byCategoryYes
disclaimersYes
recommendedActionsYes

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is covered. The description adds meaningful behavioral context beyond annotations: it returns prioritised recommended actions, explains each hold, and flags whether payment or accounting is blocked. It does not disclose rate limits, pagination, or behavior when no holds exist, which keeps it from a 5.

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 dense sentences with zero waste: the first defines content and return payload, the second defines the trigger condition. Front-loaded with the verb+resource, and every clause earns its place.

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?

An output schema exists, so return-shape explanation is not required, and the description still usefully characterises what is returned (hold meanings, owning team, release path, prioritised actions, blocked flags). For a 7-parameter read tool with full schema coverage, this is nearly complete; only edge-case behavior (e.g. no holds found, mixed released/active) is unaddressed.

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%, so the schema already documents all seven parameters in detail, including disambiguation guidance for invoiceNumber/supplierName/businessUnit and the semantics of includeReleased. The description adds no parameter-level detail beyond what the schema provides. Baseline 3 is appropriate when the schema does the heavy lifting.

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?

States a specific verb (List) and resource (holds on an Oracle Fusion Payables invoice), then enumerates the explanatory content returned (hold code meaning, owning team, revalidation, clearing steps). This is decisively distinct from siblings like get_invoice, which the description explicitly references as the prerequisite step.

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?

Provides a clear triggering condition: 'Use after get_invoice when an invoice is not paying or not accounting.' This tells the agent exactly when to reach for this tool. It doesn't name explicit exclusions or mention the other siblings (get_accounting_period_status, get_budgetary_control_impacts) that might also be relevant for a non-paying invoice, leaving a small routing gap.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv1.0.0
    • First observedget_accounting_period_status
    • First observedget_budgetary_control_impacts
    • First observedget_invoice
    • First observedget_invoice_holds

TDQS

A4.5/5.0

Scored across 4 tools

Disambiguation5/5

Each tool addresses a distinct diagnostic question: invoice facts, hold explanations, period status, and budget impacts. The descriptions explicitly reference the recommended sequence, eliminating boundary confusion.

Naming Consistency5/5

All tool names follow a uniform get_ + noun phrase pattern in snake_case, making the resource and action clear for every tool. The naming convention is perfectly consistent.

Tool Count5/5

Four tools cover a tightly scoped diagnostic domain without redundancy. Each tool earns its place and together they form a complete workflow for investigating stuck invoices.

Completeness5/5

The set covers the full diagnostic surface for the stated purpose: invoice retrieval, holds analysis, period status, and budgetary control impacts. No obvious missing operation within the read-only holds desk scope.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides secure, remote access to the Oracle Fusion Cloud Accounts Receivable REST API for managing financial data. It enables users to list, search, and retrieve detailed invoice information through natural language commands without storing credentials.
    -
  • A
    license
    B
    quality
    D
    maintenance
    Read-only access to Oracle Fusion Cloud ERP data via natural language queries, with support for accounts payable, procurement, general ledger, and more.
    30
    3
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI-powered invoice analysis and reasoning: given invoice fields, it detects missing data, inconsistencies, duplicates, and proposes actions (register, request data, mark duplicate, review) using deterministic rules.
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Self-serve MCPB demo for accounts payable invoice exception review. It performs deterministic matching across invoice, purchase order, goods receipt, vendor master, invoice history, tax code master, and payment rules.
    -