Skip to content

feat: wire CLI commands and MCP tools to SDK#22

Merged
dbejarano820 merged 2 commits into
mainfrom
feat/wire-sdk-stubs-publish-infra
Feb 22, 2026
Merged

feat: wire CLI commands and MCP tools to SDK#22
dbejarano820 merged 2 commits into
mainfrom
feat/wire-sdk-stubs-publish-infra

Conversation

@dbejarano820
Copy link
Copy Markdown
Contributor

Summary

  • Replace all placeholder stubs in CLI commands (submit, status, list, get) and MCP tools (check_status, list_documents, get_document, lookup_taxpayer) with real SDK function calls
  • Create shared auth helpers (api-client.ts) for both CLI and MCP packages — load profile, authenticate via TokenManager, return HttpClient
  • Add publish infrastructure: prepublishOnly scripts and npm keywords to all 4 packages

CLI changes

  • submit: signs XML with .p12, submits via submitAndWait(), shows accepted/rejected result
  • status: calls getStatus(), displays status + rejection reason
  • list: calls listComprobantes(), replaces hardcoded example data
  • get: calls getComprobante(), displays full document details
  • All commands accept --profile flag; submit also accepts --p12 and --pin

MCP changes

  • check_status, list_documents, get_document: authenticate via profile and call real SDK APIs
  • lookup_taxpayer: calls public lookupTaxpayer() API (no auth needed)

Tests

  • CLI: 4 new arg-presence tests for --profile, --p12, --pin
  • MCP: updated all tool tests with SDK mocks; 24 tests passing

Test plan

  • pnpm build — all 4 packages build cleanly
  • pnpm test — 911 tests pass (shared: 113, SDK: 717, CLI: 57, MCP: 24)
  • pnpm lint — clean
  • pnpm typecheck — clean
  • Manual smoke test with sandbox credentials (post-merge)

🤖 Generated with Claude Code

Replace placeholder stubs in all 4 CLI commands (submit, status, list, get)
and all 4 MCP tools (check_status, list_documents, get_document, lookup_taxpayer)
with real SDK function calls. Create shared auth helpers for both CLI and MCP.
Add prepublishOnly scripts and npm keywords to all packages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Feb 22, 2026

Greptile Summary

This PR successfully wires CLI commands and MCP tools to the SDK, replacing all placeholder stubs with real API calls. The implementation creates shared auth helpers (api-client.ts) in both packages that handle profile loading, OAuth authentication, and HttpClient creation. All four CLI commands (submit, status, list, get) and all four MCP tools (check_status, list_documents, get_document, lookup_taxpayer) now make real SDK calls.

Major Changes:

  • CLI submit command now signs XML with .p12 certificates and calls submitAndWait() for real document submission
  • CLI status, list, and get commands replaced hardcoded/placeholder data with SDK API calls
  • MCP tools replaced all placeholder responses with real API integration
  • Added publish infrastructure: prepublishOnly scripts and npm keywords across all 4 packages
  • Added profile flag support to all commands requiring authentication

Issues Found:

  • Minor: Redundant environment variable check in submit.ts line 155-157 (cleanup opportunity)
  • Minor: Error swallowing in .p12 file reading could hide useful debugging info

Test Coverage:

  • CLI: Added 4 basic arg-presence tests for new flags (--profile, --p12, --pin)
  • MCP: Updated all 24 tests with SDK mocks; tests now expect auth errors instead of placeholders
  • Missing: No integration tests for actual SDK function calls with mocked responses

Confidence Score: 4/5

  • This PR is safe to merge with good implementation quality, though integration test coverage could be stronger
  • The implementation correctly wires SDK functions with proper error handling and follows existing patterns. Auth flow is well-structured. Only minor style issues found (redundant env var check, error swallowing). Main concern is lack of integration tests for the new SDK call paths - only arg-presence tests were added for CLI commands
  • packages/cli/src/commands/submit.ts needs minor cleanup (redundant env check), and packages/cli/src/commands/commands.spec.ts would benefit from integration tests beyond arg presence

Important Files Changed

Filename Overview
packages/cli/src/utils/api-client.ts New shared auth helper for CLI commands - creates authenticated HttpClient from profile config
packages/cli/src/commands/submit.ts Wired submit command to SDK - signs XML and calls submitAndWait; redundant env var check on p12Pin
packages/mcp/src/tools/api-client.ts New shared auth helper for MCP tools - similar to CLI version but returns only HttpClient
packages/mcp/src/tools/document-tools.ts Replaced all placeholder responses with real SDK calls for check_status, list_documents, and get_document
packages/cli/src/commands/commands.spec.ts Added basic arg-presence tests for new CLI flags; no integration tests for actual SDK calls
packages/mcp/src/server.spec.ts Updated tests with SDK mocks; tools now expect auth errors instead of placeholder responses

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI/MCP
    participant AuthClient
    participant SDK
    participant Hacienda API

    User->>CLI/MCP: submit/status/list/get command
    CLI/MCP->>AuthClient: createAuthenticatedClient(profile)
    AuthClient->>SDK: loadConfig(profileName)
    AuthClient->>SDK: TokenManager.authenticate(credentials)
    SDK->>Hacienda API: POST /token (OAuth ROPC)
    Hacienda API-->>SDK: access_token
    AuthClient->>SDK: new HttpClient(envConfig, tokenManager)
    AuthClient-->>CLI/MCP: { httpClient, config }
    
    alt Submit Command
        CLI/MCP->>SDK: signAndEncode(xml, p12Buffer, p12Pin)
        SDK-->>CLI/MCP: signedXmlBase64
        CLI/MCP->>SDK: submitAndWait(httpClient, request)
        SDK->>Hacienda API: POST /recepcion
        Hacienda API-->>SDK: submission response
        SDK->>Hacienda API: GET /recepcion/{clave} (poll)
        Hacienda API-->>SDK: status response
        SDK-->>CLI/MCP: { accepted, clave, status }
    else Status/List/Get Commands
        CLI/MCP->>SDK: getStatus/listComprobantes/getComprobante
        SDK->>Hacienda API: GET /recepcion/{clave}
        Hacienda API-->>SDK: document/status data
        SDK-->>CLI/MCP: parsed response
    end
    
    CLI/MCP-->>User: formatted output
Loading

Last reviewed commit: fcbc451

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

15 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment thread packages/cli/src/commands/submit.ts Outdated
Comment on lines +155 to +157
const p12Pin = (args.pin as string | undefined) ??
config.p12Pin ??
process.env["HACIENDA_P12_PIN"];
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redundant check: config.p12Pin already contains process.env["HACIENDA_P12_PIN"] (loaded in config-manager.ts:172), so the third fallback will never be used

Suggested change
const p12Pin = (args.pin as string | undefined) ??
config.p12Pin ??
process.env["HACIENDA_P12_PIN"];
const p12Pin = (args.pin as string | undefined) ?? config.p12Pin;
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/cli/src/commands/submit.ts
Line: 155-157

Comment:
redundant check: `config.p12Pin` already contains `process.env["HACIENDA_P12_PIN"]` (loaded in config-manager.ts:172), so the third fallback will never be used

```suggestion
      const p12Pin = (args.pin as string | undefined) ?? config.p12Pin;
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +166 to +172
try {
p12Buffer = await readFile(resolve(p12Path));
} catch {
error(`Cannot read .p12 file: ${p12Path}`);
process.exitCode = 1;
return;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

swallowed error prevents seeing actual file read failure (permissions, corrupted file, etc.)

Suggested change
try {
p12Buffer = await readFile(resolve(p12Path));
} catch {
error(`Cannot read .p12 file: ${p12Path}`);
process.exitCode = 1;
return;
}
let p12Buffer: Buffer;
try {
p12Buffer = await readFile(resolve(p12Path));
} catch (err) {
error(`Cannot read .p12 file: ${p12Path}: ${err instanceof Error ? err.message : String(err)}`);
process.exitCode = 1;
return;
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/cli/src/commands/submit.ts
Line: 166-172

Comment:
swallowed error prevents seeing actual file read failure (permissions, corrupted file, etc.)

```suggestion
      let p12Buffer: Buffer;
      try {
        p12Buffer = await readFile(resolve(p12Path));
      } catch (err) {
        error(`Cannot read .p12 file: ${p12Path}: ${err instanceof Error ? err.message : String(err)}`);
        process.exitCode = 1;
        return;
      }
```

How can I resolve this? If you propose a fix, please make it concise.

- Consolidate duplicated auth helpers into SDK as `bootstrapClient()`
  with runtime validation via Zod (replaces unsafe `as` casts)
- Add MCP client caching per profile to avoid fresh ROPC auth per tool call
- Fix Greptile findings: remove redundant env var fallback, include .p12
  read error details, warn about PIN visibility in CLI args
- Add NaN validation for CLI list --limit/--offset args
- Add happy-path tests for MCP check_status, list_documents, get_document
  (5 new tests, total 29 MCP tests, 916 across all packages)
- Fix Prettier formatting on all changed files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dbejarano820 dbejarano820 merged commit a7b06f7 into main Feb 22, 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