Skip to content

feat(peakflo): expose NetSuite tools through Peakflo connections (like Xero) - #180

Merged
dimavedenyapin merged 1 commit into
mainfrom
task/fphvzrdhqccwq28rquo3c1kr
Jul 13, 2026
Merged

feat(peakflo): expose NetSuite tools through Peakflo connections (like Xero)#180
dimavedenyapin merged 1 commit into
mainfrom
task/fphvzrdhqccwq28rquo3c1kr

Conversation

@dimavedenyapin

Copy link
Copy Markdown

What & why

When a Workflo agent connects to Peakflo via pfMCP and the Peakflo tenant is connected to an accounting/ERP system, pfMCP already exposes that system's native tools using Peakflo's stored tokens — but only for Xero (#170). This PR does the same for NetSuite.

When sourceSystem == "netsuite", the Peakflo MCP server now:

  1. Lists NetSuite tools prefixed with netsuite__ (e.g. netsuite__execute_suiteql, netsuite__create_record).
  2. On call, resolves short-lived NetSuite credentials from the Peakflo credential broker (POST /internal/credentials/system-of-record/resolve, sourceSystem: "netsuite") and injects them into the NetSuite server via a credential_resolveragents never see the raw credentials.

Changes

src/servers/peakflo/main.py — generalized the Xero-only exposure into a source-system registry (SOURCE_SYSTEM_INTEGRATIONS) supporting both xero and netsuite:

  • _resolve_source_system, _get_prefixed_source_system_tools, _match_source_system_tool, _call_source_system_tool_via_peakflo_connection (generic).
  • _build_xero_credential_resolver / _build_netsuite_credential_resolver.
  • handle_list_tools / handle_call_tool now dispatch via the registry. Adding a new source of record is now a single registry entry.

src/servers/netsuite/main.py — the client was a non-functional placeholder (Bearer {consumer_key}, wrong restlets base URL, a non-existent /search endpoint). Made it real so shared credentials actually authenticate:

  • Real OAuth 1.0a TBA signing (HMAC-SHA256, account-id realm) using the already-vendored requests-oauthlib, with an automatic OAuth 2.0 Bearer fallback (auth mode chosen from whichever creds are present).
  • Correct SuiteTalk REST base URL ({account}.suitetalk.api.netsuite.com/services/rest, account id lowercased + _-); records via /record/v1/*, SuiteQL via /query/v1/suiteql with Prefer: transient.
  • Vendor search reimplemented via SuiteQL (with quote escaping).
  • Added a credential_resolver hook to create_server (mirrors Xero) so wrapper servers inject creds.

Teststests/servers/netsuite/: network-free unit tests for auth-mode selection + the broker resolver (10/10 passing), plus live TOOL_TESTS for the harness.

README — documents the SuiteTalk endpoints, the two auth modes, and the Peakflo shared-access path.

Notes

  • No workflow-builder change is required for tool exposure — like Xero, the tools flow through the Peakflo MCP server's dynamic list_tools.
  • The credential broker is already source-system agnostic; the API side just needs to resolve NetSuite credentials for sourceSystem: "netsuite" (same contract as Xero).
  • The NetSuite resolver accepts both broker credential shapes (TBA field set or OAuth2 accessToken + accountId) to be robust to how Peakflo stores the connection.

🤖 Generated with Claude Code

Mirror the Xero credential-sharing path for NetSuite. When a Peakflo tenant
is connected to NetSuite (sourceSystem="netsuite"), the Peakflo MCP server now
surfaces NetSuite tools prefixed with `netsuite__` and resolves short-lived
NetSuite credentials from the Peakflo credential broker — agents never see the
raw credentials.

- peakflo/main.py: generalize the Xero-only exposure into a source-system
  registry (SOURCE_SYSTEM_INTEGRATIONS) supporting both xero and netsuite;
  generic tool listing, prefix matching, and broker-backed dispatch.
- netsuite/main.py: make the client functional — real OAuth 1.0a TBA signing
  (HMAC-SHA256, account-id realm) with automatic OAuth 2.0 Bearer fallback,
  correct SuiteTalk REST base URL, SuiteQL-based vendor search, and a
  credential_resolver hook (like Xero) so wrapper servers can inject creds.
- tests: network-free unit tests for auth-mode selection + the broker resolver,
  plus live TOOL_TESTS for the harness.
- README: document the SuiteTalk endpoints, the two auth modes, and the
  Peakflo shared-access path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dimavedenyapin
dimavedenyapin merged commit 5e66d12 into main Jul 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant