Back to skill

Security audit

Working with Emm AI

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly coherent for remote memory and agent mission control, but it grants broad persistent authority and includes an insecure manual OAuth credential path users should review before installing.

Install only if you are comfortable giving Emm AI remote MCP access to store and search personal context, manage outputs/tasks/instructions, and potentially work with connected actions. Review memory sharing settings, avoid saving sensitive data unless you explicitly intend to, and prefer platform-managed OAuth. If you must use manual-oauth.sh, protect ~/.mcporter with owner-only permissions and know how to revoke the OAuth credential.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/manual-oauth.sh:112
Finding

OAuth Tokens and Client Secret Stored Without Explicit Permission Hardening

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
references/setup.md:18
Finding

Unpinned Global Installation of a Third-Party npm Package

Content
View full analysis
Remediation
View remediation
``` 2. State the canonical package publisher and repository so users can detect similarly named or transferred packages. 3. Publish and verify an expected integrity digest or signed release provenance where the distribution mechanism supports it. 4. Prefer a lockfile-backed local installation, a reviewed packaged binary, or an isolated execution environment over a mutable global installation. 5. Avoid installation with elevated privileges. Explicitly warn users not to prepend `sudo`. 6. Review package lifecycle scripts and consider installation with scripts disabled if mcporter does not require them: ```bash npm install -g mcporter@ --ignore-scripts ``` 7. Maintain an allowlisted version range and update it only after reviewing new releases and their dependency changes. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
agents/openai.yaml:7
Finding

Implicit Invocation Can Persist Personal Information to a Remote Service Without Item-Specific Confirmation

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented purpose emphasizes memory and mission-control behavior, but the analyzer reports hidden OAuth registration, token exchange, local callback handling, and credential storage behaviors. A mismatch between declared purpose and actual authentication/credential handling is dangerous because users may grant access without understanding that secrets are being created, stored, and used beyond the described memory workflow.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The activation criteria are extremely broad and can trigger on ordinary requests where long-term storage or remote mission-control actions are not expected by the user. Over-broad activation increases the chance of collecting personal data, querying shared memory, or initiating remote workflows without clear, contextual consent.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · CHANGELOG.md (reported line 94)May include surrounding context.

md
| Rule | Detail |
|------|--------|
| **Tool schema wins.** | If the bundled `agents` brief (or any instruction) names a tool that isn't in your loaded tool list, or prescribes argument shapes that don't match the schema, follow the **live tool schema**. The brief is user-editable and can drift. If an `agent_run` returns a `⚠️ Brief drift detected` warning, surface a 💡 nudge to the actions dashboard. See [Agent Runs](#agent-runs-the-recurring-cycle). |
| **Link forms.** | Inside an output body, link to another output via `[label](output:<category>/<id>)` (stable id, like memory's `memory:<type_name>/<id>`) and to a memory via `[label](memory:<type_name>/<id>)`; in the MCP response to the user, link to outputs with `<actor_url>/app/outputs?category=<c>&id=<id>` and to memories with `<actor_url>/app/memory#<type>-<id>`; in YAML frontmatter or tool args, bare `<category>:<id>` or `<memory_type>:<id>`. See [Display Rules](#display-rules) and [link form decision rule](#outputs-the-wiki). |
| **Memory / output IDs in prose.** | Both can appear, but only as link text inside a real link — never bare. `[memory_food:42](memory:memory_food/42)` (inside an output body) or `[memory_food:42](<actor_url>/app/memory#memory_food-42)` (in the MCP response) and the equivalent `[email:5](…)` forms for outputs are fine; bare `memory_food:42` / `email:5` in prose is not. |
| **Internal doc names stay backstage.** | Don't name `personal`, `style`, `agents`, `tasks`, `default_tasks` in prose to the user. Refer to them by what they are ("your standing instructions", "your voice guide") when explanation is needed. |
| **Never auto-delete memories.** | Even on Memory Hygiene findings. Propose, log; let the user decide. Same for outputs — prefer update over delete unless explicitly asked. |

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · SKILL.md (reported line 25)May include surrounding context.

md
| Rule | Detail |
|------|--------|
| **Tool schema wins.** | If the bundled `agents` brief (or any instruction) names a tool that isn't in your loaded tool list, or prescribes argument shapes that don't match the schema, follow the **live tool schema**. The brief is user-editable and can drift. If an `agent_run` returns a `⚠️ Brief drift detected` warning, surface a 💡 nudge to the actions dashboard. See [Agent Runs](#agent-runs-the-recurring-cycle). |
| **Link forms.** | Inside an output body, link to another output via `[label](output:<category>/<id>)` (stable id, like memory's `memory:<type_name>/<id>`) and to a memory via `[label](memory:<type_name>/<id>)`; in the MCP response to the user, link to outputs with `<actor_url>/app/outputs?category=<c>&id=<id>` and to memories with `<actor_url>/app/memory#<type>-<id>`; in YAML frontmatter or tool args, bare `<category>:<id>` or `<memory_type>:<id>`. See [Display Rules](#display-rules) and [link form decision rule](#outputs-the-wiki). |
| **Memory / output IDs in prose.** | Both can appear, but only as link text inside a real link — never bare. `[memory_food:42](memory:memory_food/42)` (inside an output body) or `[memory_food:42](<actor_url>/app/memory#memory_food-42)` (in the MCP response) and the equivalent `[email:5](…)` forms for outputs are fine; bare `memory_food:42` / `email:5` in prose is not. |
| **Internal doc names stay backstage.** | Don't name `personal`, `style`, `agents`, `tasks`, `default_tasks` in prose to the user. Refer to them by what they are ("your standing instructions", "your voice guide") when explanation is needed. |
| **Never auto-delete memories.** | Even on Memory Hygiene findings. Propose, log; let the user decide. Same for outputs — prefer update over delete unless explicitly asked. |

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · SKILL.md (reported line 58)May include surrounding context.

md
| Rule | Detail |
|------|--------|
| **Tool schema wins.** | If the bundled `agents` brief (or any instruction) names a tool that isn't in your loaded tool list, or prescribes argument shapes that don't match the schema, follow the **live tool schema**. The brief is user-editable and can drift. If an `agent_run` returns a `⚠️ Brief drift detected` warning, surface a 💡 nudge to the actions dashboard. See [Agent Runs](#agent-runs-the-recurring-cycle). |
| **Link forms.** | Inside an output body, link to another output via `[label](output:<category>/<id>)` (stable id, like memory's `memory:<type_name>/<id>`) and to a memory via `[label](memory:<type_name>/<id>)`; in the MCP response to the user, link to outputs with `<actor_url>/app/outputs?category=<c>&id=<id>` and to memories with `<actor_url>/app/memory#<type>-<id>`; in YAML frontmatter or tool args, bare `<category>:<id>` or `<memory_type>:<id>`. See [Display Rules](#display-rules) and [link form decision rule](#outputs-the-wiki). |
| **Memory / output IDs in prose.** | Both can appear, but only as link text inside a real link — never bare. `[memory_food:42](memory:memory_food/42)` (inside an output body) or `[memory_food:42](<actor_url>/app/memory#memory_food-42)` (in the MCP response) and the equivalent `[email:5](…)` forms for outputs are fine; bare `memory_food:42` / `email:5` in prose is not. |
| **Internal doc names stay backstage.** | Don't name `personal`, `style`, `agents`, `tasks`, `default_tasks` in prose to the user. Refer to them by what they are ("your standing instructions", "your voice guide") when explanation is needed. |
| **Never auto-delete memories.** | Even on Memory Hygiene findings. Propose, log; let the user decide. Same for outputs — prefer update over delete unless explicitly asked. |

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · SKILL.md (reported line 101)May include surrounding context.

md
| Rule | Detail |
|------|--------|
| **Tool schema wins.** | If the bundled `agents` brief (or any instruction) names a tool that isn't in your loaded tool list, or prescribes argument shapes that don't match the schema, follow the **live tool schema**. The brief is user-editable and can drift. If an `agent_run` returns a `⚠️ Brief drift detected` warning, surface a 💡 nudge to the actions dashboard. See [Agent Runs](#agent-runs-the-recurring-cycle). |
| **Link forms.** | Inside an output body, link to another output via `[label](output:<category>/<id>)` (stable id, like memory's `memory:<type_name>/<id>`) and to a memory via `[label](memory:<type_name>/<id>)`; in the MCP response to the user, link to outputs with `<actor_url>/app/outputs?category=<c>&id=<id>` and to memories with `<actor_url>/app/memory#<type>-<id>`; in YAML frontmatter or tool args, bare `<category>:<id>` or `<memory_type>:<id>`. See [Display Rules](#display-rules) and [link form decision rule](#outputs-the-wiki). |
| **Memory / output IDs in prose.** | Both can appear, but only as link text inside a real link — never bare. `[memory_food:42](memory:memory_food/42)` (inside an output body) or `[memory_food:42](<actor_url>/app/memory#memory_food-42)` (in the MCP response) and the equivalent `[email:5](…)` forms for outputs are fine; bare `memory_food:42` / `email:5` in prose is not. |
| **Internal doc names stay backstage.** | Don't name `personal`, `style`, `agents`, `tasks`, `default_tasks` in prose to the user. Refer to them by what they are ("your standing instructions", "your voice guide") when explanation is needed. |
| **Never auto-delete memories.** | Even on Memory Hygiene findings. Propose, log; let the user decide. Same for outputs — prefer update over delete unless explicitly asked. |

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · SKILL.md (reported line 235)May include surrounding context.

md
| Rule | Detail |
|------|--------|
| **Tool schema wins.** | If the bundled `agents` brief (or any instruction) names a tool that isn't in your loaded tool list, or prescribes argument shapes that don't match the schema, follow the **live tool schema**. The brief is user-editable and can drift. If an `agent_run` returns a `⚠️ Brief drift detected` warning, surface a 💡 nudge to the actions dashboard. See [Agent Runs](#agent-runs-the-recurring-cycle). |
| **Link forms.** | Inside an output body, link to another output via `[label](output:<category>/<id>)` (stable id, like memory's `memory:<type_name>/<id>`) and to a memory via `[label](memory:<type_name>/<id>)`; in the MCP response to the user, link to outputs with `<actor_url>/app/outputs?category=<c>&id=<id>` and to memories with `<actor_url>/app/memory#<type>-<id>`; in YAML frontmatter or tool args, bare `<category>:<id>` or `<memory_type>:<id>`. See [Display Rules](#display-rules) and [link form decision rule](#outputs-the-wiki). |
| **Memory / output IDs in prose.** | Both can appear, but only as link text inside a real link — never bare. `[memory_food:42](memory:memory_food/42)` (inside an output body) or `[memory_food:42](<actor_url>/app/memory#memory_food-42)` (in the MCP response) and the equivalent `[email:5](…)` forms for outputs are fine; bare `memory_food:42` / `email:5` in prose is not. |
| **Internal doc names stay backstage.** | Don't name `personal`, `style`, `agents`, `tasks`, `default_tasks` in prose to the user. Refer to them by what they are ("your standing instructions", "your voice guide") when explanation is needed. |
| **Never auto-delete memories.** | Even on Memory Hygiene findings. Propose, log; let the user decide. Same for outputs — prefer update over delete unless explicitly asked. |

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · references/tool-surface.md (reported line 91)May include surrounding context.

md
| Rule | Detail |
|------|--------|
| **Tool schema wins.** | If the bundled `agents` brief (or any instruction) names a tool that isn't in your loaded tool list, or prescribes argument shapes that don't match the schema, follow the **live tool schema**. The brief is user-editable and can drift. If an `agent_run` returns a `⚠️ Brief drift detected` warning, surface a 💡 nudge to the actions dashboard. See [Agent Runs](#agent-runs-the-recurring-cycle). |
| **Link forms.** | Inside an output body, link to another output via `[label](output:<category>/<id>)` (stable id, like memory's `memory:<type_name>/<id>`) and to a memory via `[label](memory:<type_name>/<id>)`; in the MCP response to the user, link to outputs with `<actor_url>/app/outputs?category=<c>&id=<id>` and to memories with `<actor_url>/app/memory#<type>-<id>`; in YAML frontmatter or tool args, bare `<category>:<id>` or `<memory_type>:<id>`. See [Display Rules](#display-rules) and [link form decision rule](#outputs-the-wiki). |
| **Memory / output IDs in prose.** | Both can appear, but only as link text inside a real link — never bare. `[memory_food:42](memory:memory_food/42)` (inside an output body) or `[memory_food:42](<actor_url>/app/memory#memory_food-42)` (in the MCP response) and the equivalent `[email:5](…)` forms for outputs are fine; bare `memory_food:42` / `email:5` in prose is not. |
| **Internal doc names stay backstage.** | Don't name `personal`, `style`, `agents`, `tasks`, `default_tasks` in prose to the user. Refer to them by what they are ("your standing instructions", "your voice guide") when explanation is needed. |
| **Never auto-delete memories.** | Even on Memory Hygiene findings. Propose, log; let the user decide. Same for outputs — prefer update over delete unless explicitly asked. |

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · SKILL.md (reported line 58)May include surrounding context.

md
- Each entry carries `expires_at`. A run past that is swept to `abandoned` by the server; you never need to clean up someone else's stale run yourself.
  - `agent_run_complete(last_open=true)` only acts when **exactly one** run is open account-wide — then it is unambiguous whoever is asking. If anything else is open it refuses with `-32095 explicit_run_id_required` and names the candidates, even if one of them looks like yours: the server cannot always tell two clients apart, so it will not guess with a live run. Pass the `run_id` from your own `agent_run()` response — the by-id close is exact and never depends on who you are. That is the reliable close path; treat `last_open` as a convenience for the single-run case.
- `suggested_actions` — only populated when `mode == "instructions_update"`. Lists concrete work the unlocked window invites (review self-reviews, rationalise tasks, harvest 💡 nudges).
- `conventions` — display rules, link forms, attribution cap, and search freshness, mirrored live from this file (see [Display Rules](#display-rules)). A skill-less LLM reading only `status()` gets table-stakes correctness from this field without loading this skill.
- `limits.*`, `links.*`, `tools_recommended`, `your_client_has_only_used_reads` — see [tool surface](references/tool-surface.md#status--non-safety-fields) for the field-by-field reference.

- **Memory only** (`pillars_enabled == ["memory"]`) — only `memory_search`, `memory_save`, `memory_get`, `memory_update`, `memory_move`, `memory_delete`, `memory_types`, `memory_create_type`, `memory_delete_type` apply. Skip the *Outputs*, *Instructions*, *Agent Runs*, and *One-off tasks* sections.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · references/tool-surface.md (reported line 91)May include surrounding context.

md
- Each entry carries `expires_at`. A run past that is swept to `abandoned` by the server; you never need to clean up someone else's stale run yourself.
  - `agent_run_complete(last_open=true)` only acts when **exactly one** run is open account-wide — then it is unambiguous whoever is asking. If anything else is open it refuses with `-32095 explicit_run_id_required` and names the candidates, even if one of them looks like yours: the server cannot always tell two clients apart, so it will not guess with a live run. Pass the `run_id` from your own `agent_run()` response — the by-id close is exact and never depends on who you are. That is the reliable close path; treat `last_open` as a convenience for the single-run case.
- `suggested_actions` — only populated when `mode == "instructions_update"`. Lists concrete work the unlocked window invites (review self-reviews, rationalise tasks, harvest 💡 nudges).
- `conventions` — display rules, link forms, attribution cap, and search freshness, mirrored live from this file (see [Display Rules](#display-rules)). A skill-less LLM reading only `status()` gets table-stakes correctness from this field without loading this skill.
- `limits.*`, `links.*`, `tools_recommended`, `your_client_has_only_used_reads` — see [tool surface](references/tool-surface.md#status--non-safety-fields) for the field-by-field reference.

- **Memory only** (`pillars_enabled == ["memory"]`) — only `memory_search`, `memory_save`, `memory_get`, `memory_update`, `memory_move`, `memory_delete`, `memory_types`, `memory_create_type`, `memory_delete_type` apply. Skip the *Outputs*, *Instructions*, *Agent Runs*, and *One-off tasks* sections.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/manual-oauth.sh (reported line 34)May include surrounding context.

sh
echo ""
echo "==> Registering dynamic OAuth client..."
REG=$(curl -sf -X POST "$REGISTER_URL" \
  -H "Content-Type: application/json" \
  -d "{\"client_name\":\"mcporter-cli\",\"redirect_uris\":[\"$REDIRECT_URI\"],\"grant_types\":[\"authorization_code\",\"refresh_token\"],\"response_types\":[\"code\"],\"token_endpoint_auth_method\":\"client_secret_post\"}")

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/manual-oauth.sh (reported line 95)May include surrounding context.

sh
# --- Exchange code for tokens ---
echo "==> Exchanging code for tokens..."
TOKEN_RESPONSE=$(curl -sf -X POST "$TOKEN_URL" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=${OAUTH_CODE}&redirect_uri=${REDIRECT_URI}&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&code_verifier=${CODE_VERIFIER}")

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The script writes access tokens, refresh tokens, and client secrets in plaintext to ~/.mcporter/credentials.json without setting restrictive file permissions or using an OS-backed secret store. Any local user, backup system, or other process with access to that file could recover long-lived credentials and impersonate the user against the MCP service.

Content

Scanner excerpt · scripts/manual-oauth.sh (reported line 112)May include surrounding context.

sh
const path = require('path');
const os = require('os');

const VAULT_PATH = path.join(os.homedir(), '.mcporter', 'credentials.json');

const descriptor = { name: 'emm', url: '${MCP_URL}', command: null };
const hash = crypto.createHash('sha256').update(JSON.stringify(descriptor)).digest('hex').slice(0, 16);

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill declares no explicit tool scope while instructing use of a wide set of remote-capable tools, including networked MCP actions and potentially shell-capable environments per the analyzer. Lack of least-privilege scoping increases the blast radius if the skill is mis-invoked, misconfigured, or combined with prompt-injection from external content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill description highlights convenience but does not prominently warn that it stores personal data remotely and may orchestrate external or connected-system actions. Users may unknowingly expose sensitive information or approve an agent workflow without understanding persistence and action side effects.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

The skill explicitly instructs the agent to proceed with overlapping runs and not ask the user for permission when another run is already open. Although framed as concurrency guidance, it authorizes autonomous continuation of potentially state-changing workflows on shared surfaces, which can surprise users and amplify unintended actions.

Content

Scanner excerpt · SKILL.md (reported line 52)May include surrounding context.

md
- `runs` — `{open, open_count, last_completed}`. **`open` is a list** of every run currently open, newest first; it is empty when nothing is running. (It was a single object or `null` before skill 2.2.0 — if you are reading `runs.open.run_id` you have an older skill and will get `undefined`.)

  **Overlapping runs are supported.** A scheduled Autopilot run and an interactive one can be open at the same time, as can two scheduled ones. Starting a run never closes anyone else's. So when `open` is non-empty, the question is not "may I proceed" — it is "what do I need to be careful about":
  - **Proceed.** Do not ask the user for permission to run because another run is open, and do not wait for it.
  - **Expect the shared surfaces to move under you.** The dashboard, the wiki and the task queue may all change mid-cycle. Re-read before you overwrite, and pass the `updated_at` you read as `if_match` on `output_update` / `output_delete` so a clobber is refused (`revision_conflict`) rather than applied silently.
  - **Close only the run you started.** Compare each entry's `started_by_client_id` with your `your_session_id`, and `started_by_transport_session_id` with your `your_transport_session_id` when both are present. A run that is not yours is not yours to close — the other agent is still using it. **A matching `started_by_client_id` is not proof it is yours:** two sessions of the same registered client (a second tab, or a scheduled run on the same credential) share that id and the server cannot tell them apart. Unless you hold the `run_id` from your own `agent_run()` response, treat a same-client run as someone else's and close by explicit `run_id`, not `last_open=true`.
  - Each entry carries `expires_at`. A run past that is swept to `abandoned` by the server; you never need to clean up someone else's stale run yourself.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · SKILL.md (reported line 421)May include surrounding context.

md
- **Emm tools are missing, or `status()` itself errors:** the connector likely isn't configured, isn't enabled for this conversation, or auth has expired. See the [setup guide](references/setup.md)'s unreachable-server checklist.
- **A tool call returns a structured error** (an outer code like `-32099`, `-32098`, `-32097`, `-32096`, `-32095`, `-32094`, `-32093`, `-32092`, `-32091`, with an inner `data.code`): see [error handling during a run](references/mission-control.md#error-handling-during-a-run) for the full code table and per-code remedy. Most carry the fix in `action_required` — don't retry blindly.
- **The tool returns the literal string `"No approval received."`** instead of a structured envelope: some MCP clients (notably Claude.ai's web UI) gate `list_connections`, `describe_method`, and `execute_method` behind a per-tool approval prompt — sometimes non-deterministically. If the user denies (or the prompt times out), the server never sees the call at all. Treat this as a client-side denial, not a server error: tell the user the call was denied at their client and ask them to grant the connector permission in their client's settings (Claude.ai → MCP connector → tool approvals). Don't retry.

## Custom Categories

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The default prompt tells the agent to both recall preferences and proactively save information from the session, and it also uses broad phrases like "when I ask" for mission-control actions. In a long-term memory skill, this creates ambiguity about when sensitive user data should be persisted or when higher-impact workflow tools should be invoked, increasing the risk of unintended data storage or unauthorized task execution from loosely related user requests.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Implicit invocation is enabled even though this skill has access to persistent memory and mission-control capabilities via a remote MCP server. That means the skill may activate based on broad contextual cues rather than explicit user intent, which is especially dangerous here because activation can expose personal context, store new sensitive information, or trigger standing-instruction/task workflows without a clear opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This guidance explicitly encourages storing durable personal preferences, stakeholder views, and organizational signals, but it provides no guardrails around consent, data minimization, sensitivity screening, or handling of regulated data. In a long-term memory skill, that omission increases the likelihood that users or agents will persist sensitive personal or third-party information in ways that create privacy, compliance, and trust risks.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file explicitly instructs the agent to treat quoted dashboard comments as trusted task input even though the dashboard is user-editable content. That collapses the trust boundary between operational instructions and untrusted data, enabling prompt injection or unsafe tool actions if malicious or compromised content is placed in the dashboard.

Content

No source excerpt is available for this finding.

Ssd 1

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

Marking user-editable dashboard comments as inherently trusted instructions creates a direct prompt-injection path from stored content into agent control flow. In this skill, the danger is amplified because the surrounding mission-control system can trigger runs, update outputs, process tasks, and potentially influence connected-device or long-term-memory actions.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/manual-oauth.sh (reported line 34)May include surrounding context.

sh
echo ""
echo "==> Registering dynamic OAuth client..."
REG=$(curl -sf -X POST "$REGISTER_URL" \
  -H "Content-Type: application/json" \
  -d "{\"client_name\":\"mcporter-cli\",\"redirect_uris\":[\"$REDIRECT_URI\"],\"grant_types\":[\"authorization_code\",\"refresh_token\"],\"response_types\":[\"code\"],\"token_endpoint_auth_method\":\"client_secret_post\"}")

External Transmission

Medium
Category
Data Exfiltration
Confidence
83% confidence
Finding

This request sends the authorization code, PKCE verifier, client ID, and client secret to the token endpoint using form-encoded arguments embedded directly in the curl command line. While this is normal for OAuth token exchange, placing secrets in command-line arguments can expose them to local process inspection, shell history/logging, or debugging tools on the host.

Content

Scanner excerpt · scripts/manual-oauth.sh (reported line 95)May include surrounding context.

sh
# --- Exchange code for tokens ---
echo "==> Exchanging code for tokens..."
TOKEN_RESPONSE=$(curl -sf -X POST "$TOKEN_URL" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=${OAUTH_CODE}&redirect_uri=${REDIRECT_URI}&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&code_verifier=${CODE_VERIFIER}")

Static analysis

No suspicious patterns detected.