Skip to content

feat: add Copy as cURL to audit log entries - #1046

Merged
helpcodeai merged 11 commits into
HelpCode-ai:mainfrom
AYUshJaiswal454:feat/audit-log-copy-as-curl
Oct 13, 2026
Merged

helpcodeai merged 11 commits into
HelpCode-ai:mainfrom
AYUshJaiswal454:feat/audit-log-copy-as-curl

Conversation

@AYUshJaiswal454

Copy link
Copy Markdown
Contributor

Summary

Adds a "Copy as cURL" button to each expanded audit log row on the Audit Log (/logs) page to quickly replay the recorded MCP tools/call against AnythingMCP outside of an AI client.

Changes

  • cURL Builder (packages/frontend/src/lib/curl.ts):
    • Implemented buildToolCallCurl({ origin, serverId, toolName, args, authMode }).
    • Replays the MCP tools/call with standard JSON-RPC 2.0 envelope and MCP-Protocol-Version: 2025-06-18.
    • Verified that AnythingMCP's stateless per-server endpoint (/mcp/:serverId) accepts bare tools/call requests directly without requiring an initialize handshake.
    • Formats the request body with a quoted heredoc (--data-binary @- <<'JSON' ... JSON), ensuring that quotes (', "), dollar signs ($), backticks (`), and newlines in arguments survive verbatim without shell expansion issues.
    • Credential protection: Emits placeholder environment variables (-H "X-API-Key: $AMCP_MCP_API_KEY" for legacy/both modes, -H "Authorization: Bearer $AMCP_ACCESS_TOKEN" for OAuth2). Never inserts real secrets or dashboard session tokens (amcp_token). Recursively redacts sensitive credential fields in tool arguments matching REDACTED_KEY_PATTERN.
  • UI Action (packages/frontend/src/app/logs/page.tsx):
    • Added "Copy as cURL" button to the expanded row next to the User/Server meta line.
    • Reuses copyText from @/lib/clipboard with visual feedback ("Copied!" checkmark for 2s, error fallback if denied).
    • Automatically queries server.info() for mcpAuthMode to format the correct auth header.
    • Properly disables the button with an informative tooltip when:
      • The row came through the shared /mcp endpoint (log.mcpServer is null).
      • The stored input parameters were truncated (log.input._amcp_truncated is present).
      • The tool name is missing.
  • Shared Origin Utility (packages/frontend/src/lib/origin.ts):
    • Extracted getApiOrigin() (localhost -> port 4000, otherwise window.location.origin) and reused it in logs/page.tsx, mcp-server/[id]/page.tsx, and app/page.tsx.
  • Documentation (docs/api-reference.md):
    • Added a "Replay a Tool Call" note with example cURL command and instructions to export AMCP_MCP_API_KEY / AMCP_ACCESS_TOKEN.
  • Tests (packages/frontend/tests/e2e/audit-log-curl.spec.ts):
    • Unit tests covering header generation, auth mode switching, origin normalization, special character preservation, argument credential redaction, and empty/null handling.
    • E2E Playwright test covering clipboard copy, format verification, and disabled state tooltips.

Type

  • Bug fix
  • New feature
  • Documentation
  • Refactoring
  • Performance improvement
  • Other

Testing

  • Added/updated unit tests: 6 unit tests in audit-log-curl.spec.ts passing.
  • Tested manually:
    • Verified local stateless endpoint behavior: bare tools/call with MCP-Protocol-Version: 2025-06-18 returns HTTP 200 with result event stream.
    • Tested Playwright e2e test (npx playwright test tests/e2e/audit-log-curl.spec.ts) verifying full UI interaction, clipboard copy, and disabled tooltip states (7/7 passed).
    • Ran existing redesign.spec.ts smoke test (passed).
    • Ran npx tsc --noEmit -p tsconfig.json in packages/frontend (0 errors).
    • Ran npm run lint in packages/frontend (0 errors).
    • Ran npm run build in packages/frontend (compiled successfully).

Checklist

  • My code follows the existing code style
  • I have tested my changes locally
  • I have updated documentation (if applicable)
  • All existing tests pass (npm test)
  • This PR has a descriptive title

Related Issues

Closes #999
Relates to #850

@github-actions

Copy link
Copy Markdown

👋 Welcome, @AYUshJaiswal454, and thanks for opening your first PR on AnythingMCP!

A few quick pointers:

  • Make sure CI is green before requesting review (Backend, Frontend, Playwright, CodeQL, Trivy).
  • If this is a new adapter, the parametrised catalog.spec.ts test will validate it automatically.
  • Sign off your commits if you can — it's not blocking, just nice to have.

Someone from the core team will look at this within ~48h. If you don't hear back, please ping us in Discussions / Q&A.

⭐ While you wait — if you find AnythingMCP useful, a star helps others discover it.

@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


1 out of 2 committers have signed the CLA.
✅ (AYUshJaiswal454)[https://github.com/AYUshJaiswal454]
❌ @ayush Kumar
Ayush Kumar seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@AYUshJaiswal454

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

@AYUshJaiswal454

Copy link
Copy Markdown
Contributor Author

recheck

@notlakshitha notlakshitha left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hi! Nice feature, and the security thinking up front is great.

What's good

  • The auth value is always a placeholder, so no real token ends up in the copied command.
  • The request body goes through a quoted heredoc, so shell characters in the arguments are passed through literally.
  • The button is disabled, with a clear reason, for rows it can't replay.
  • Pulling out getApiOrigin() removes duplicated code in three places.

Suggestions:

  1. The URL sits inside double quotes and uses encodeURI, so a server ID containing $ or a backtick could still be expanded by the shell. encodeURIComponent plus single quotes would make it safe whatever the ID contains.
  2. The redaction only checks key names. It misses auth, pwd, jwt, session, bearer and access_key, and it doesn't catch secrets stored in values. Values deeper than 10 levels also come back unredacted.
  3. A replayed [REDACTED] value fails silently. A warning, or a note at the top of the copied command, would help.
  4. log.tool?.name || log.toolId (page.tsx:112) puts a database ID where the tool name should go, so the replay calls a tool that doesn't exist. Disabling the button there might be better.
  5. Any auth mode other than oauth2 gets the API-key header. And until the server info loads, the mode defaults to 'both', so a quick click could copy the wrong header.
  6. The pure unit tests sit under Playwright e2e. Maybe add one that proves an argument containing a heredoc breakout like \nJSON\n stays safe.
  7. Nit (page.tsx:443): the truncation check can be simplified to '_amcp_truncated' in log.input.

None of these block the PR in my view. Nice work!

AYUshJaiswal454 and others added 3 commits October 12, 2026 20:57
…cted arguments

Quote the endpoint URL in single quotes with an encoded server id, so nothing in it reaches the shell. Replay only a row's tool name, never its database id. Redact subtrees deeper than the walk instead of passing them through, catch a few more credential key names, and start the command with a comment when arguments were redacted. Tests for heredoc breakout, shell characters in the id and deep values.

@helpcodeai helpcodeai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @AYUshJaiswal454, nice feature, and thanks @notlakshitha for the careful review. I went through it for security and pushed a few changes on top (8849ee7) rather than send you another round:

  1. The URL is now in single quotes with encodeURIComponent on the server id, so nothing in it can be expanded by the shell. In practice the id is always a UUID, but this way it doesn't matter.
  2. The replay only uses log.tool?.name. Falling back to toolId would have copied a database id as the tool name, so rows without a name are now disabled instead.
  3. Values nested deeper than the redaction walk are replaced instead of passed through, and the key list also catches pwd, jwt, bearer, access_key and session_id/session_key. I left auth out on purpose, it's a common name for whole config objects.
  4. When something was redacted, the command starts with a comment saying so, so a replay doesn't fail silently.
  5. Tests for a heredoc breakout attempt, shell characters in the id and deep values, plus a line in the docs about the redaction.

The heredoc itself was already safe: JSON.stringify escapes newlines, so the payload is always one line and can't produce a bare JSON line.

One thing on your side: the cla check fails because your commit is authored as ayushkumar@Ayushs-MacBook-Air-6.local, which isn't linked to your GitHub account, so the bot can't match it to your signature. Could you add that address to your GitHub account (or amend the commit with your GitHub email and force-push)? Then I'll merge.

- Use single-quoted URLs with encodeURIComponent for shell safety
- Recursively redact sensitive keys and values with depth boundaries
- Emit warning comments when replaying redacted or truncated arguments
- Disable copy action when tool name is missing instead of DB ID fallback
- Handle authMode loading race conditions and respect clientInfo authMethod
- Prevent heredoc delimiter collision on arguments containing JSON
- Add Playwright and builder unit tests for all edge cases
…ements with full redaction and edge-case handling
github-actions Bot added a commit that referenced this pull request Oct 12, 2026
@AYUshJaiswal454

Copy link
Copy Markdown
Contributor Author

recheck

@AYUshJaiswal454

Copy link
Copy Markdown
Contributor Author

Hi, thanks for pushing the fixes to my PR!

I signed the CLA, and GitHub shows the signature event in the PR timeline, but CLA Assistant still fails with:

Committers of Pull Request number 1046 have to sign the CLA

I also commented recheck, but the check still appears to show the previous failed run.

Could you please check which commit author the CLA workflow is failing to recognize and help resolve the signature issue? Also, four workflows are still awaiting maintainer approval. Could you approve those workflows so the required backend and frontend checks can run?

I haven't changed or rewritten the commit history. Thank you for your help!

@helpcodeai

Copy link
Copy Markdown
Contributor

It's the first commit, e097ec3. It's authored as ayushkumar@Ayushs-MacBook-Air-6.local (your Mac's default git email), and since that address isn't on any GitHub account the bot can't tie it to your signature. All your later commits use kumarayush08757@gmail.com and are fine.

No need to rewrite history for it: you signed with this account and the commit is clearly yours, and we squash-merge, so the commit on main is attributed to your GitHub account anyway. For next time, git config --global user.email kumarayush08757@gmail.com avoids it.

Your follow-up changes look good to me too, the value-based redaction is a nice addition.

@helpcodeai
helpcodeai enabled auto-merge (squash) October 13, 2026 11:44
@helpcodeai
helpcodeai merged commit 8d4460a into HelpCode-ai:main Oct 13, 2026
12 of 13 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 13, 2026
@AYUshJaiswal454
AYUshJaiswal454 deleted the feat/audit-log-copy-as-curl branch October 13, 2026 18:14
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🎃 Add "Copy as cURL" to an audit log entry to replay the MCP tool call

3 participants