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 savetitle(optional): Short title for the memorymemory_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 querylimit(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 statusget_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_sessionlogin_url(optional): Required for create_new_session — URL of the login pagecredential_id(optional): For create_new_session — link to a stored credentialverification_url(optional): For create_new_session — URL to verify successful loginaccount_id(optional): For create_new_session — link to a discovered accountcapabilities(optional): For update_capabilities — dict of capability flagsdescription(optional): For update_description/update_sessionscope(optional): For update_description/update_session
How to switch sessions:
- First call
manage_auth_session(action="list_sessions")to see available sessions - Close the browser:
browser_close() - Switch:
manage_auth_session(action="replace_current_session", session_id="...") - 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