Skip to main content

Mcp Tools

Available Pter MCP Tools

You have access to the following MCP tools for coordinating with Pter. These are native MCP tools that you can call directly.

These MCP tools are the primary way to store knowledge in Peter. All discovered services, endpoints, findings, credentials, and observations MUST be stored via these tools. Markdown files are only for supplementary reports (e.g., the report_path field on findings) and working scratch notes — they are not queryable by other agents or visible in the platform.

manage_tasks

Unified task management tool. Use different actions to create tasks, update status, or get details.

Actions:

action="create"

Create a new task. Use this to create tasks for the next phase or subtasks.

manage_tasks(
action="create",

title="Short human-readable label", # Required
task_description="Clear description of the task to be done", # Required
done_definition="Criteria for task completion", # Required
phase_id=2, # Required: Phase ID to assign task to
service_ids=[1, 3], # REQUIRED for P3-P8: service IDs this task relates to
parent_task_id="..." # Optional: Your task ID if this is a subtask
)

service_ids is REQUIRED for P3-P8 tasks. The tool rejects P3-P8 tasks without it. Look up services via manage_services(action="list") to get IDs. P4 tasks with endpoint_id auto-populate from the endpoint's service.

action="update_status"

Update the status of your current task. ALWAYS call this when done or failed.

manage_tasks(
action="update_status",

task_id=TASK_ID,
status="done", # "done" or "failed"
summary="Brief summary of what was accomplished",
key_learnings=["Learning 1", "Learning 2"], # Optional
failure_reason="..." # Required when status is "failed"
)

action="get_details"

Get detailed information about a specific task.

manage_tasks(
action="get_details",
task_id=42
)

manage_assessments

Track security hypotheses and tests. Create assessments when you identify potential attack vectors, match CVEs, or want to chain findings.

Actions:

action="create"

manage_assessments(
action="create",

title="SQL Injection on /api/users/search",
description="POST parameter 'query' appears to be concatenated into SQL",
assessment_type="vector", # vector, cve, or chain
targets=["endpoint://42"], # Required, non-empty. Format: entity_type://id
status="pending" # pending → in_progress → confirmed / refuted
)

action="update"

manage_assessments(
action="update",

assessment_id=42,
status="confirmed",
description="Confirmed via time-based blind injection"
)

action="submit_result"

manage_assessments(
action="submit_result",

assessment_id=42, # Required
status="confirmed", # Required: "confirmed" or "refuted"
description="## Investigation Result\n\n**Verdict: Exploitable**\n\n...", # Required
report_path="work/docs/exploitation/exploitation_42_CWE-89.md" # Required
)

action="get" / action="list"

assessment = manage_assessments(action="get", assessment_id=42)
all_assessments = manage_assessments(action="list")

manage_findings

Create validated, report-worthy security findings. Use this after confirming an assessment.

Actions:

action="create"

manage_findings(
action="create",

# --- REQUIRED fields ---
title="Time-based blind SQL injection in /api/users search",
description=(
"The /api/users/search endpoint is vulnerable to time-based blind SQL injection "
"via the 'query' parameter. The parameter value is interpolated directly into a "
"SQL WHERE clause without parameterization.\n\n"
"An attacker can extract arbitrary data from the database by observing response "
"timing differences. The users table contains email addresses, password hashes, "
"and API keys for all tenants — this is a full database compromise vector.\n\n"
"No authentication is required. The search endpoint is public-facing and has no "
"rate limiting."
),
affected_components=["endpoint://42"], # Required, non-empty. Format: entity_type://id
report_path="work/docs/exploitation/exploitation_42.md", # Required: path to report file
cvss_vector="CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", # Required: severity is derived from this

# --- optional fields ---
cwe_id="CWE-89",
reproduction_steps=(
"1. Send a baseline search request:\n"
" $ curl -s -w '\\nTime: %{time_total}s\\n' -X POST https://target.com/api/users/search \\\n"
" -H 'Content-Type: application/json' \\\n"
" -d '{\"query\": \"admin\"}'\n\n"
" Output: {\"users\": [{\"id\": 1, ...}]}\n"
" Time: 0.12s\n\n"
"2. Send a time-based injection payload:\n"
" $ curl -s -w '\\nTime: %{time_total}s\\n' -X POST https://target.com/api/users/search \\\n"
" -H 'Content-Type: application/json' \\\n"
" -d '{\"query\": \"admin\\' AND SLEEP(5)-- -\"}'\n\n"
" Output: {\"users\": []}\n"
" Time: 5.14s\n"
" Expected: <0.5s response or input rejection. Actual: 5s delay confirms injection."
),
recommended_fix="Use parameterized queries in user_repository.search(). Replace f-string SQL with sqlalchemy text() bind parameters.",
evidence=[
{
"type": "request",
"command": "curl -s -w '\\nTime: %{time_total}s\\n' -X POST https://target.com/api/users/search -H 'Content-Type: application/json' -d '{\"query\": \"admin\\' AND SLEEP(5)-- -\"}'",
"response": "{\"users\": []}\nTime: 5.14s"
}
],
assessment_id=42, # Link to the confirming assessment
)

action="update"

manage_findings(
action="update",

finding_id=1,
status="validated", # draft → validated → submitted
cvss_vector="CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N", # Recalculated after further testing
)

manage_credentials

Store discovered credentials. Use this for any credential values found during testing — NOT save_memory.

Actions:

action="create"

manage_credentials(
action="create",

credential_type="api_key", # user_password, jwt, api_key, session_cookie, other
value="sk-live-abc123...",
account_id=5, # Optional — link to Account
status="valid", # unknown, valid, invalid, expired
notes="Found in /config/settings.json"
)

action="list" / action="get"

all_creds = manage_credentials(action="list")
by_account = manage_credentials(action="list_by_account", account_id=5)

manage_accounts

Track discovered accounts (identities) on the target. Use this to register accounts found during testing.

Actions:

action="create"

manage_accounts(
action="create",

username="admin@example.com", # Required
account_role="admin", # Optional: user, developer, admin, service_account, tester
account_status="verified", # Optional: unverified, verified, active, deletion_pending
notes="Found via user enumeration on /api/users" # Optional
)

action="update"

manage_accounts(
action="update",

account_id=5,
account_status="active",
notes="Confirmed active via login"
)

action="get" / action="list"

account = manage_accounts(action="get", account_id=5)
all_accounts = manage_accounts(action="list")

manage_attack_chains

Link multiple findings into exploit sequences that demonstrate chained attack paths.

Actions:

action="create"

manage_attack_chains(
action="create",

title="IDOR to Admin Takeover", # Required
description="Chain: IDOR leaks admin email -> password reset -> account takeover",
overall_severity="critical", # Optional: critical, high, medium, low, informational
impact="Full admin account takeover", # Optional
findings=[ # Optional: list of finding dicts
{"finding_id": 1, "step_order": 1, "role_description": "IDOR leaks admin email"},
{"finding_id": 3, "step_order": 2, "role_description": "Password reset via email"},
{"finding_id": 7, "step_order": 3, "role_description": "Admin panel access"}
]
)

action="update"

manage_attack_chains(
action="update",

chain_id=1, # Required
overall_severity="high",
status="validated"
)

action="get" / action="list"

chain = manage_attack_chains(action="get", chain_id=1)
all_chains = manage_attack_chains(action="list")

save_memory

Save observations and learnings to the shared memory for future agents.

Use save_memory for: observations, learnings, error fixes, decisions, codebase knowledge. Do NOT use save_memory for: credential values (use manage_credentials), confirmed vulnerabilities (use manage_findings), attack hypotheses (use manage_assessments).

Parameters:

  • content (required): The knowledge to save
  • title (optional): Short title for the memory
  • memory_type (optional): One of: "discovery", "learning", "warning", "error_fix", "decision", "codebase_knowledge"
  • references (optional): List of entity references in "type://id" format (e.g., ["service://1", "endpoint://42"]) Valid types: endpoint, service, technology, flow, account, credential, finding, assessment, attack_chain, memory, agent, task

query_memories

Search the shared knowledge base. Use this before starting complex work.

Parameters:

  • query (required): Semantic search query
  • limit (optional): Maximum number of results (default: 10)
  • memory_type (optional): Filter by memory type (singular string, not a list)

Authentication Session Management

You have access to multiple authenticated sessions. Use these when you need to switch accounts for any reason: testing with a different user, cross-account verification, your current session is blocked or rate-limited, or you need a fresh account for your work.

manage_auth_session

Manage authentication sessions, API keys, and metadata for cross-account testing.

Parameters:

  • action (required): One of:
    • list_sessions: Get all available auth sessions with their status
    • get_current_session: Get info about your currently active session (requires session_id)
    • replace_current_session: Switch to a different session (requires session_id)
    • create_new_session: Register a new login session (requires login_url; optional credential_id, verification_url, account_id)
    • reauth: Re-authenticate an expired session (requires session_id)
    • get_otp_code: Get OTP code for a session (requires session_id)
    • update_capabilities: Update session capabilities (requires session_id, capabilities dict)
    • update_description: Update session description (requires session_id, description; optional scope)
    • update_session: Update session metadata (requires session_id; optional description, scope)
  • session_id (optional): Required for most actions except list_sessions and create_new_session
  • login_url (optional): Required for create_new_session — URL of the login page
  • credential_id (optional): For create_new_session — link to a stored credential
  • verification_url (optional): For create_new_session — URL to verify successful login
  • account_id (optional): For create_new_session — link to a discovered account
  • capabilities (optional): For update_capabilities — dict of capability flags
  • description (optional): For update_description/update_session
  • scope (optional): For update_description/update_session

How to switch sessions:

  1. First call manage_auth_session(action="list_sessions") to see available sessions
  2. Close the browser: browser_close()
  3. Switch: manage_auth_session(action="replace_current_session", session_id="...")
  4. Open browser - you are now authenticated as the other user

IMPORTANT: You must close the browser before switching sessions. Switching with the browser open will cause authentication failures.

When to use this:

  • Cross-account testing (IDOR, privilege escalation)
  • Your current session is blocked, rate-limited, or expired
  • You need to verify behavior as a different user
  • You need to set up a new login session (also store the credential via manage_credentials)
  • You need to store metadata (user_id, profile_id) discovered during testing
  • You need to re-authenticate an expired session