# SAP MCP

Use this skill when an agent needs to operate the SAP MCP server through MCP,
configure local or remote launch, inspect the loaded profile, or reason about
safe signing behavior.

## First Step

If the user says "Start SAP MCP", "Initialize SAP MCP", "Load SAP", or "SAP
mode", treat it as the activation command. Call `sap_agent_start` when it is
available, then call `sap_agent_runtime_status` with the closest intent and
`sap_prepare_action` when the request is more than a status check. For cross-agent,
marketplace, identity, payment, or standards-interoperability work, also call
`sap_agent_standard_context`. Then call `sap_skills_bundle` with
`includeContents: true`. Load the returned SAP MCP skill contents into context
before selecting advanced tools.

If the MCP runtime exposes prompts, use `sap-agent-intent-router` as the compact
decision prompt before paid calls, registry writes, escrow flows, identity
updates, or after SAP/x402/MCP errors. It routes the user intent to hosted
reads, `sap_payments_*`, unsigned builders, transaction finalization, or repair
without requiring a long pasted prompt from the user.

Always inspect runtime context through MCP tools, not by reading config files:

1. `sap_agent_start`
2. `sap_agent_runtime_status` with `intent: "connection"`, `"paid-call"`, `"registry-write"`, `"transaction-finalize"`, `"escrow"`, `"identity"`, or `"general"`
3. `sap_prepare_action` with the closest intent before paid calls, swaps, registry writes, identity updates, Escrow V2, external x402 agents, premium streams, or transaction finalization
4. `sap_agent_standard_context` when the workflow touches MCP/x402/pay.sh, A2A-style discovery, OASF-style exports, AP2-style mandates, marketplace publication, or public claims
5. `sap_prepare_mandate` before bounded agent-commerce workflows that need spend caps, allowed tools/protocols, confirmation thresholds, and proof-tape fields. This returns an unsigned planning artifact, not a wallet authorization.
6. `sap_agent_context` for compact micro-read agent/directory orientation before broad discovery
7. `sap_export_agent_oasf` when a known owner wallet needs an OASF-style profile export for directories or agent networks
8. `sap_skills_bundle` with `includeContents: true`
9. `sap_pricing_catalog` before estimating hosted paid call tiers
10. `sap_agent_next_action` before retrying after any SAP MCP error or partial write result
11. `sap_skills_upgrade_plan` when local skills are missing or stale
12. `sap_runtime_repair_plan` when hosted tools are connected but `sap_payments` is missing
13. `sap_protocol_invariants` before SAP registry writes or when treasury, protocol fee, hosted write routing, or local signer routing is unclear
14. `sap_agent_identity_plan` before agent registration, profile-image updates, Metaplex identity, SNS linking, or full identity setup
15. `sap_profile_current`
16. `sap_profile_list`
17. `sap_profile_public_key`
18. `sap_network_stats`

For simple "are you connected?" checks, do not dump tool counts or inspect
local files. Use `sap_agent_runtime_status` first and answer with the hosted
endpoint, accountless/non-custodial model, local bridge readiness if visible,
and the next exact action.

The server profile is the source of truth. Environment variables from the MCP
client must not override profile-owned RPC or wallet settings unless
`SAP_MCP_ALLOW_ENV_CONFIG_OVERRIDE=true`.

## Response Language

Answer in the same natural language as the user's latest request. If the user
asks in English, answer in English even when previous chat history, tool output,
or repository docs contain Italian. Keep tool names, protocol IDs, addresses,
and error strings unchanged.

## Discovery Rules

- Treat SAP registry, balances, SNS ownership, quotes, settlement status, and
  agent profile reads as fresh data. Do not rely on old chat memory when the
  user asks for current state; use exact lightweight reads first, then paid
  discovery only when enrichment or broad search is needed.
- Treat session memory as operational context and proof tape, not cached market
  or on-chain truth. It may store active profile names, public wallet keys,
  runtime namespace availability, receipts, signatures, and error
  classifications. It must not be used as truth for token prices, Jupiter
  quotes/orders, balances, blockhashes, simulations, liquidity, routes, or SAP
  account state.
- Use low-cost exact/base micro-reads first when the wallet, PDA, or a small
  orientation page is enough: `sap_agent_context`, `sap_get_agent`, `sap_get_agent_profile`,
  `sap_get_agent_stats`, `sap_is_agent_active`, `sap_get_global_state`, and
  `sap_list_agents` with `limit <= 20`, `view: "compact"`, and
  `includeProtocolIndexes: false`.
- Use `sap_get_network_overview` for live ecosystem counters.
- Use `sap_discover_agents` for targeted paid hosted discovery. Prefer
  `query`, `wallet`, `agentPda`, `protocol`, `capability`, `capabilities`,
  `hasX402Endpoint`, and small `limit` values before broad scans.
- Use `sap_list_all_agents` when the user asks for all current SAP ecosystem
  agents. It performs global on-chain `AgentAccount` enumeration and returns
  `pagination.nextCursor` when more pages are available.
- Use `sap_list_agents` for a compact micro-read orientation page first. Larger
  pages, `view: "full"`, hydration, protocol index summaries, and global scans
  are read-premium.
- Use `sap_fetch_protocol_index` when a specific protocol ID is known.
- If a capability lookup returns zero results, retry with `query` or `wallet`
  before saying an agent is absent. AgentAccount rows are canonical; indexes can
  lag.
- Do not tell the user that all-agent enumeration is impossible unless
  `sap_list_all_agents` fails and you report the exact failure.

## Tool Name Prefixes

Some MCP clients display SAP tools as `mcp_sap_<tool>`. The callable tool name
inside this server omits the client prefix. Example: a client may display
`mcp_sap_jupiter_getQuote`, while the MCP tool name is `jupiter_getQuote`.

## Upstream References

Use these official upstream references for the latest SAP SDK documentation and
source skill taxonomy:

- Synapse SAP SDK docs: https://github.com/OOBE-PROTOCOL/synapse-sap-sdk/tree/main/docs
- Synapse SAP SDK skills: https://github.com/OOBE-PROTOCOL/synapse-sap-sdk/tree/main/skills

Use the bundled routing map for local MCP tool selection:

- `skills/sap-mcp/TOOL_REFERENCE.md`
- `USER_DOCS/05_AGENT_SKILLS_TOOL_ROUTING.md`

SAP MCP startup and skill bootstrap tools are free context/setup tools. Call
`sap_agent_start`, `sap_agent_runtime_status`, `sap_agent_context`,
`sap_prepare_action`, `sap_agent_standard_context`, `sap_prepare_mandate`,
`sap_export_agent_oasf`, `sap_agent_next_action`, `sap_pricing_catalog`,
`sap_skills_list`, `sap_skills_bundle`, `sap_skills_upgrade_plan`,
`sap_runtime_repair_plan`, and local `sap_skills_install` directly. Do not
route startup, runtime status, standards context, mandate planning, OASF export,
pricing catalog, skill listing, bundling, upgrade planning, runtime repair
planning, or installation through
`sap_x402_paid_call` or `sap_payments_call_paid_tool`. On hosted remote MCP, use
`sap_skills_bundle` to download skill contents; the hosted server cannot
install files onto the caller's local machine. Local installation belongs to the
wizard, desktop app, addon installer, or a local stdio SAP MCP process.
If skills or runtime bridge config are stale, call `sap_skills_upgrade_plan` or
`sap_runtime_repair_plan` first. These tools return the pinned latest-release
commands and preserve the non-custodial local signing model.

## Hosted MCP Local Bridge Setup

Canonical hosted endpoint:

```text
https://mcp.sap.oobeprotocol.ai/mcp
```

Public server metadata:

```json
{
  "name": "sap-mcp-server",
  "title": "SAP MCP Server | OOBE Protocol",
  "status": "online",
  "protocol": {
    "primary": "mcp",
    "transport": "streamable-http",
    "protocolVersion": "2025-06-18"
  },
  "endpoints": {
    "landing": "https://mcp.sap.oobeprotocol.ai/",
    "mcp": "https://mcp.sap.oobeprotocol.ai/mcp",
    "serverInfo": "https://mcp.sap.oobeprotocol.ai/server.json",
    "wizardDescriptor": "https://mcp.sap.oobeprotocol.ai/.well-known/sap-mcp-wizard.json",
    "wizardInstallScript": "https://mcp.sap.oobeprotocol.ai/wizard/install.sh"
  },
  "authentication": {
    "schemes": ["none", "x402"],
    "bearerRequired": false
  },
  "security": {
    "keypairBytesExposed": false,
    "storesUserKeypairs": false,
    "rpcSecretsExposed": false,
    "wizardConfigDirectory": "~/.config/mcp-sap"
  }
}
```

Hosted users still need a local SAP MCP profile when they sign x402/pay.sh
payments, SAP transactions, Solana transactions, SNS operations, or settlement
actions. The hosted MCP server is not a wallet custodian.

For hosted paid tools, use the native x402 flow. If the client runtime cannot
attach `PAYMENT-SIGNATURE` itself, use the local SAP MCP `sap_payments` bridge.
Call `sap_agent_runtime_status` first for routing, then
`sap_payments_wallet_guard` to inspect capability-only local signer guardrails
without exposing wallet paths or keypair bytes. Then call
`sap_payments_readiness` to verify the active profile, signer, SOL/USDC
balance, policy limits, and bridge status. Then call
`sap_payments_call_paid_tool` for the hosted paid tool. This is not a separate
hosted signing plugin: it is the local SAP MCP process using the user's
configured SAP profile wallet or external signer to sign the x402 payment
payload, retry the hosted tool call, and return the receipt.
`sap_x402_paid_call` is a backward-compatible alias only for older runtime
snippets. Neither helper must be treated as a remote hosted signing service.
If paid-call settlement stalls, the runtime reports `ClosedResourceError`, or
multiple sessions seem to fight over the bridge, call
`sap_payments_process_status` and ask the user to fully quit/reopen the runtime
instead of killing node/npx processes mid-session.
The local bridge should be a singleton per SAP profile/runtime. If a runtime
config is stale and omits `SAP_MCP_RUNTIME_ID`, SAP MCP uses a stable fallback
lock and exits orphaned bridge-only processes when the parent runtime is gone.

When connected to hosted SAP MCP, `signerConfigured: false` on the remote
server means the hosted server is non-custodial. It does not mean the remote
tool surface is unavailable. Do not silently switch to local stdio just because
a hosted call requires x402 payment or because the hosted server does not hold
the user's signer. Use the hosted x402 flow first; ask the user before using a
local stdio fallback.

Hosted remote is accountless. If `sap_profile_current` returns
`accountModel: hosted-remote-accountless`, do not describe `default` as the
user's profile and do not infer the user's wallet from the hosted server. To
inspect the local user profile, wallet, signer status, and payment policy, call
the local `sap_payments.sap_payments_wallet_guard` and
`sap_payments.sap_payments_readiness` bridge tools when they are configured.
Use `sap_payments.sap_payments_profile_current` only as a narrower compatibility
profile check. Agents may report the active profile and signer public key, but
must not read or print wallet paths.

Basic wallet and price-readiness checks are free hosted reads. Call
`sol_get_balance`, `spl-token_getBalance`, `spl-token_getTokenAccounts`,
`sap_x402_get_balance`, `magicblock_balance`, `jupiter_getPrice`,
`pyth_getPrice`, and `coingecko_getTokenPrice` directly on the hosted server
when the user needs fresh readiness data. Do not send these checks through
`sap_payments_call_paid_tool`, and do not summarize a readiness read as a
facilitator `BlockhashNotFound` problem unless a paid x402 tool actually
returned that error. Use `jupiter_getHoldings` only when the user needs enriched
read-premium portfolio context.

Before any paid tool call, use `sap_estimate_tool_cost` with the tool name to
get the exact pricing tier, estimated USD cost, and recommended `maxPriceUsd`.
This prevents silent cap aborts and failed x402 attempts on local-signer-only
tools. For local-signer-only tools (e.g. `sap_register_agent`), the estimate
will say `tier: "local-signer-only"` and tell you to use the local
`sap_payments_*` equivalent instead of `sap_payments_call_paid_tool`.
For any intent-level workflow, call `sap_prepare_action` before execution. It
returns the correct hosted/local route, fresh-data requirements, confirmation
policy, retry rules, and proof-tape shape without charging x402.

If a hosted paid tool returns `BlockhashNotFound`,
`transaction_simulation_failed`, `smart_wallet_simulation_failed`, `node is
behind`, `minimum context slot`, `fetch failed`, `gateway timeout`, or a
response marked `retryable: true`, treat it as a transient x402/Solana RPC
settlement error. Do not claim that SAP MCP is down unless `/health` also
fails. Do not bypass the paid hosted path with terminal/direct RPC. Retry
through the local `sap_payments_call_paid_tool` bridge with the same tool name
and arguments, `confirm: true`, and `maxAttempts: 5` so a fresh payment payload
is created. Use `sap_x402_paid_call` only when a runtime still exposes the
legacy alias.

When a hosted paid/write builder returns `transactionBase64`, `transaction`, or
another unsigned Solana transaction payload, finalize it locally with
`sap_payments_finalize_transaction`. Do not call hosted `sap_sign_transaction`
for a user-owned signer, do not create `.js`/`.mjs` signing scripts, and do not
read keypair JSON.

If hosted SAP MCP returns `hosted_local_signer_required`, no x402 payment was
charged. The tool requires a local user signature or has no hosted unsigned
builder yet. For `sap_register_agent`, call
`sap_payments.sap_payments_register_agent` with the same registration fields and
`confirm: true`; it runs the SAP registry write through the local signer bridge
without charging a hosted x402 access fee. For `sap_update_agent`, call
`sap_payments.sap_payments_update_agent` with the intended replacement fields
and `confirm: true`; use it for public agent image/profile metadata updates via
`agentUri` or `metadataUri`. For Escrow V2, call the matching
`sap_escrow_build_*_transaction` hosted builder and finalize with
`sap_payments_finalize_transaction`. For other direct writes, do not retry the
same hosted tool; use the local SAP MCP profile or an unsigned hosted builder
plus `sap_payments_finalize_transaction` when one exists.

For registry lifecycle completion, do not treat a transaction signature alone
as enough. After `sap_payments_register_agent`, verify `success`,
`agentRegistered`, `agentPda`, `confirmationStatus`, `protocolComplete`, and
the returned `protocolFee.status`. `success: true` means both the agent account
and protocol fee invariant were verified. If `success` is false while
`agentRegistered` is true, report that the account may exist but the SAP
protocol registration lifecycle is not complete. After
`sap_payments_update_agent`, fetch the agent again and confirm the changed
fields before saying an image, metadata, pricing, or capability update is done.
If an update returns Anchor 3012, `AccountNotInitialized`, or `pricing_menu`, do
not call runtime repair or retry the same write. Route it through
`sap_agent_next_action` and `sap_protocol_invariants`; it is an SAP on-chain
registry lifecycle issue, not a missing local bridge.

Before any write-like operation, use this routing order:

1. Hosted read or paid hosted read: direct hosted tool, or
   `sap_payments_call_paid_tool` when x402 is required.
2. Hosted unsigned transaction builder: finalize with
   `sap_payments_finalize_transaction` and `submit: true` when the user confirms.
3. SAP registry registration/update: use `sap_payments_register_agent` or
   `sap_payments_update_agent`; do not retry hosted accountless writes.
4. External x402 HTTP provider: use `sap_payments_call_external_x402`.
5. Missing bridge: call `sap_runtime_repair_plan`, then tell the user to run the
   pinned repair command or desktop wizard repair path.

### MagicBlock Private Payments

SAP MCP exposes 21 MagicBlock tools across three protocol domains: ER Router
(6 read-only JSON-RPC), Private Payments API (13 REST tools including
ensure-crank), and VRF (2 on-chain tools).

Private transfers and private swaps use the Hydra delivery crank for scheduled
settlement. The API requires specific fields for private mode:

- `magicblock_transfer` with `visibility: "private"`: `minDelayMs`, `maxDelayMs`,
  and `split` are optional with defaults (`"0"`, `"0"`, `1`). SAP MCP passes these
  defaults explicitly when the user omits them.
- `magicblock_swap` with `visibility: "private"`: `destination`, `minDelayMs`,
  `maxDelayMs`, and `split` are all required. SAP MCP validates these before
  calling the API and rejects `asLegacyTransaction: true` (private swaps require
  v0 VersionedTransactions).

If a private transfer or swap has been submitted but the recipient has not
received funds, call `magicblock_ensureCrank` with the mint address to force a
transfer queue crank attempt. This does not move funds; it triggers the existing
queued delivery.

wSOL (`So11111111111111111111111111111111111111112`) is supported as both
input and output mint in private mode. The API only rejects
`nativeDestinationAccount`, not the wSOL mint itself. Private swap output
delivered as wSOL lands in the recipient's wSOL ATA, not as native SOL.

When summarizing a hosted connection, use language like:
"server is non-custodial; user signatures come from the local SAP profile or
external signer." Avoid saying "signer not configured", "read-only only",
"writes unavailable", or "remote MCP broken" unless a specific tool returns
that exact operational error.

For simple connection questions such as "are you connected to SAP MCP?", answer
briefly. Include connected yes/no, endpoint, mode, non-custodial status, and
one next action. Do not dump the full tool catalog, protocol list, or category
summary unless the user explicitly asks what tools are available. Startup logs
or registration logs prove that the MCP server started; they do not prove that
the current agent runtime injected every tool as callable. If `tools/list`
works but callable functions are missing, report a runtime reload/injection
issue and ask the user to restart the runtime.

If `sap_payments` tools are missing after the user says the wizard completed,
call `sap_runtime_repair_plan`. Do not ask the user to manually rebuild their
runtime config unless the repair plan has already failed or runtime startup logs
show a concrete package/runtime error.

`sap_agent_runtime_status` includes a `runtimeDoctor` object. Use it as the
fast secret-free local preflight for mode, signer, wallet path presence, policy
limits, RPC, and paid/write readiness. It does not replace
`sap_payments_readiness`, which is still required before paid/write work when
the local bridge is visible because it checks live bridge balances and signer
capability.

For agent identity work, load the matching focused skills before acting:

- register, update, profile image, capability, pricing, or x402 endpoint:
  `sap-agent-registry`
- NFT-backed identity, MPL Core, Metaplex metadata, creator/collection flows:
  `sap-nft-metaplex`
- `.sol` domain ownership, records, or primary identity:
  `sap-sns`

The canonical field and pipeline reference is
`docs/16_AGENT_IDENTITY_REGISTRY_PIPELINE.md`. Follow it before registry writes.

## Profile Tools

| Tool | Purpose |
| --- | --- |
| `sap_profile_current` | Show loaded profile, active profile, RPC, network, program, signer public key |
| `sap_profile_list` | List available profiles without exposing wallet paths |
| `sap_profile_public_key` | Show profile agent public key |
| `sap_profile_switch` | Reload runtime to another profile; requires `confirm: true` |

## Wizard And CLI

Create or update a profile:

```bash
npx sap-mcp-wizard
# or
npx sap-mcp-config wizard
```

### `npx sap-mcp-config` Usage

Use `sap-mcp-config` for all local profile and wallet configuration. Do not
edit generated JSON files manually unless you are repairing a broken profile.

Recommended first setup:

```bash
npx sap-mcp-config wizard
```

The wizard creates `~/.config/mcp-sap/`, stores profile configs as
`config-<profile>.json`, and creates or links dedicated keypairs under the SAP
MCP config directory. It must not use or overwrite the Solana CLI keypair unless
the user explicitly chooses that path.

Show the currently loaded/active config:

```bash
npx sap-mcp-config show
npx sap-mcp-config doctor
npx sap-mcp-config doctor --json
npx sap-mcp-config info
```

List, inspect, and switch profiles:

```bash
npx sap-mcp-config profiles
npx sap-mcp-config profile-info
npx sap-mcp-config profile <profile-name>
```

Show the public agent identity:

```bash
npx sap-mcp-config pubkey
```

Check wallet status without printing keypair bytes:

```bash
npx sap-mcp-config wallet
```

For MCP-native checks, call:

```text
sap_payments.sap_payments_wallet_guard
sap_payments.sap_payments_readiness
```

These return signer capability and readiness state without returning local
wallet paths or private material.

Update safe scalar settings:

```bash
npx sap-mcp-config set rpcUrl https://api.mainnet-beta.solana.com
npx sap-mcp-config set logLevel info
npx sap-mcp-config set maxTxValueSol 10
npx sap-mcp-config set requireApprovalAboveSol 1
npx sap-mcp-config set dailyLimitSol 100
```

MCP client configuration should prefer the dynamic profile manager over
duplicated RPC or wallet env vars. In dynamic mode the server reads
`~/.config/mcp-sap/.active-profile`, so the user can change profile with
`sap-mcp-config profile <name>` and then restart the MCP client:

```yaml
mcp_servers:
  sap:
    command: node
    args:
      - /absolute/path/to/sap-mcp-server/dist/cli.js
    cwd: /absolute/path/to/sap-mcp-server
    env:
      SAP_MCP_ALLOW_ENV_CONFIG_OVERRIDE: "false"
      SAP_LOG_LEVEL: info
```

Only pin a fixed profile when that is intentional:

```yaml
env:
  SAP_MCP_PROFILE: gianni-market-nft-agent
  SAP_MCP_CONFIG_PATH: ~/.config/mcp-sap/config-gianni-market-nft-agent.json
  SAP_MCP_ALLOW_ENV_CONFIG_OVERRIDE: "false"
  SAP_LOG_LEVEL: info
```

Avoid passing `SAP_WALLET_PATH` or `SAP_MCP_RPC_URL` from the MCP client unless
the user intentionally wants env overrides and has set
`SAP_MCP_ALLOW_ENV_CONFIG_OVERRIDE=true`.

Hosted Claude/Codex/OpenClaw-style JSON:

```json
{
  "mcpServers": {
    "sap": {
      "url": "https://mcp.sap.oobeprotocol.ai/mcp",
      "transport": "streamable-http"
    }
  }
}
```

Hosted Hermes global `~/.hermes/mcp.json` JSON:

```json
{
  "sap": {
    "url": "https://mcp.sap.oobeprotocol.ai/mcp",
    "transport": "streamable-http"
  }
}
```

Hosted Hermes profile YAML:

```yaml
mcp_servers:
  sap:
    url: https://mcp.sap.oobeprotocol.ai/mcp
    transport: streamable-http
```

Show active profile:

```bash
npx sap-mcp-config show
npx sap-mcp-config profile-info
npx sap-mcp-config pubkey
```

List and switch profiles:

```bash
npx sap-mcp-config profiles
npx sap-mcp-config profile <name>
```

Start local MCP over stdio:

```bash
npx sap-mcp-server start
```

Operator-only: start your own remote MCP over Streamable HTTP:

```bash
SAP_MCP_AUTH_TYPE=api_key \
SAP_MCP_API_KEYS=<api-key>=<operator-id> \
npx sap-mcp-remote
```

Do not ask hosted users to run their own HTTP server unless they are deploying
their own VPS/operator instance.

Do not call a local free `stdio` SAP MCP server as an implicit substitute for
hosted paid tools. Local stdio is a developer fallback only when the user asks
for local execution or the client cannot perform remote Streamable HTTP/x402.

## Signing Rules

- Do not read wallet/keypair files.
- Do not print local wallet paths from runtime config.
- Do not create temporary `.js`/`.mjs` signing scripts.
- Treat `sap_payments` as a signer capability surface, not direct keypair access.
- Do not ask the user to paste private key bytes.
- Use `sap_preview_transaction` before any signing.
- Use `sap_sign_transaction` only after preview and policy checks.
- Use `sap_submit_signed_transaction` only for a signed transaction that the
  user or policy explicitly allows.
- If a transaction exceeds policy limits, stop and ask the user for approval
  through the surrounding agent UI.

## MCP Tool Reference

See `TOOL_REFERENCE.md` in this skill directory for the SAP tool mapping to
the most specific SAP skill domain. Use live `tools/list` for the exact runtime
count because upstream SDK tool registries can evolve.
