How to Use the fileUrl from Upload Response for MCP Scanning in AI-Infra-Guard
To use the fileUrl from an upload response for MCP scanning, extract the URL from the upload endpoint's JSON response and assign it to the attachments field in the MCP scan payload before submitting the task to /api/v1/app/taskapi/tasks.
When scanning local AI tools or Skill projects with Tencent's AI-Infra-Guard, the CLI must first upload the project archive to the A.I.G. server to obtain a temporary fileUrl. This URL enables the server to access the uploaded file for MCP scanning without requiring direct file transfer in the scan request itself, streamlining the analysis of local project directories.
Understanding the MCP Scan Upload Flow
The AI-Infra-Guard client (aig_client.py) orchestrates a two-phase process when handling local files for MCP analysis. First, the client invokes the private _upload_file() method to send a multipart request to POST /api/v1/app/taskapi/upload. The server responds with a JSON object containing the temporary fileUrl, which the client then automatically inserts into content["attachments"] within the scan payload. Finally, the client submits this payload to /api/v1/app/taskapi/tasks with type="mcp_scan", allowing the server to fetch and analyze the file directly from the provided URL.
Step-by-Step: Using fileUrl for MCP Scanning
Step 1: Upload the File to Obtain the fileUrl
To begin, upload your project archive using the upload endpoint. In skills/aig-scanner/scripts/aig_client.py, the _upload_file() method handles this by sending a multipart form-data request with a unique boundary:
boundary = "----AigClientBoundary9876543210"
# ... multipart body construction ...
req = urllib.request.Request(
f"{BASE_URL}/api/v1/app/taskapi/upload",
data=body,
headers={"Content-Type": f"multipart/form-data; boundary={boundary}"},
method="POST",
)
The server returns a JSON response with this structure:
{
"status": 0,
"data": {
"fileUrl": "https://aig.example.com/uploads/abcd1234.zip",
"filename": "myproject.zip",
"size": 123456
}
}
Step 2: Extract the fileUrl from the Response
After a successful upload, extract the fileUrl value from the data object in the response. The client stores this in upload_data["fileUrl"] for subsequent use in the scan submission.
Step 3: Construct the MCP Scan Payload
Before submitting the scan, assign the URL to the attachments key within the payload's content object. According to the implementation in aig_client.py, the client executes:
content["attachments"] = upload_data["fileUrl"]
The complete payload structure must include the task type and optional prompt:
{
"type": "mcp_scan",
"content": {
"attachments": "https://aig.example.com/uploads/abcd1234.zip",
"prompt": "Audit this AI-tool for security issues"
}
}
Step 4: Submit the Scan Request
Submit the payload to the task creation endpoint. The server downloads the file from the provided URL and initiates the MCP analysis:
payload = {
"type": "mcp_scan",
"content": {
"attachments": file_url,
"prompt": prompt,
},
}
req = urllib.request.Request(
f"{BASE_URL}/api/v1/app/taskapi/tasks",
data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json", "username": USERNAME},
method="POST",
)
Practical Code Examples
Using the CLI (Automated Approach)
The simplest approach uses the built-in scan-ai-tools command in skills/aig-scanner/scripts/aig_client.py, which handles the upload and URL injection automatically when you provide the --local-path argument:
python3 skills/aig-scanner/scripts/aig_client.py scan-ai-tools \
--local-path /path/to/myproject.zip \
--prompt "Please audit this AI-tool"
This command invokes _upload_file() to obtain the fileUrl, places it into content["attachments"], and submits the mcp_scan task via _submit_and_poll() without requiring manual intervention.
Manual Python Implementation
For custom integrations or automated pipelines, reproduce the flow manually using standard library modules:
import json
import urllib.request
import os
import mimetypes
BASE_URL = os.getenv("AIG_BASE_URL")
USERNAME = os.getenv("AIG_USERNAME", "openclaw")
API_KEY = os.getenv("AIG_API_KEY", "")
def _headers(ct="application/json"):
h = {"username": USERNAME}
if ct:
h["Content-Type"] = ct
if API_KEY:
h["API-KEY"] = API_KEY
return h
def upload_file(path):
boundary = "----AigClientBoundary9876543210"
filename = os.path.basename(path)
ctype = mimetypes.guess_type(filename)[0] or "application/octet-stream"
with open(path, "rb") as f:
file_data = f.read()
body = (
f"--{boundary}\r\n"
f'Content-Disposition: form-data; name="file"; filename="{filename}"\r\n'
f"Content-Type: {ctype}\r\n\r\n"
).encode() + file_data + f"\r\n--{boundary}--\r\n".encode()
req = urllib.request.Request(
f"{BASE_URL}/api/v1/app/taskapi/upload",
data=body,
headers={**_headers(ct=None), "Content-Type": f"multipart/form-data; boundary={boundary}"},
method="POST",
)
with urllib.request.urlopen(req, timeout=120) as resp:
return json.loads(resp.read())["data"]
def submit_mcp_scan(file_url, prompt="Audit this AI-tool"):
payload = {
"type": "mcp_scan",
"content": {
"attachments": file_url,
"prompt": prompt,
},
}
req = urllib.request.Request(
f"{BASE_URL}/api/v1/app/taskapi/tasks",
data=json.dumps(payload).encode(),
headers=_headers(),
method="POST",
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read())
# Usage example
upload_info = upload_file("/path/to/myproject.zip")
result = submit_mcp_scan(upload_info["fileUrl"])
print("Task submitted, session ID:", result["data"]["session_id"])
Direct API Payload Construction
If you already possess a valid fileUrl from a previous upload session, you can skip the upload step and construct the JSON payload directly:
curl -X POST https://aig.example.com/api/v1/app/taskapi/tasks \
-H "Content-Type: application/json" \
-H "Username: openclaw" \
-H "API-KEY: $API_KEY" \
-d '{
"type": "mcp_scan",
"content": {
"attachments": "https://aig.example.com/uploads/abcd1234.zip",
"prompt": "Audit the uploaded AI-tool"
}
}'
Key Source Files and Functions
The upload-to-scan workflow is implemented across several key functions in skills/aig-scanner/scripts/aig_client.py:
_upload_file(): Handles the multipart upload to/api/v1/app/taskapi/uploadand returns the response data containingfileUrl.cmd_scan_ai_tools(): CLI entry point defined around lines 48-57 that detects the--local-pathflag and triggers the upload branch before MCP scanning._submit_and_poll(): Located around lines 10-17, this function submits the final payload to/api/v1/app/taskapi/taskswith thefileUrlproperly embedded incontent["attachments"].
Summary
- Obtain the fileUrl by uploading your archive to
POST /api/v1/app/taskapi/uploadusing the_upload_file()method inaig_client.py. - Embed the URL in the MCP scan payload by assigning it to
content["attachments"]before submission to/api/v1/app/taskapi/tasks. - Use type
mcp_scanwhen constructing the task payload to ensure the server processes the file with the correct scanner. - The CLI automates this entire workflow when using
scan-ai-tools --local-path, making manual URL handling optional for standard use cases. - The
fileUrlis a temporary, server-internal link that the MCP scanner uses to fetch your file for analysis.
Frequently Asked Questions
What is the fileUrl in the AI-Infra-Guard upload response?
The fileUrl is a temporary, server-accessible URL returned by the A.I.G. upload endpoint (/api/v1/app/taskapi/upload) that points to your uploaded file. According to the implementation in aig_client.py, the MCP scanner uses this URL to download and analyze the file contents without requiring you to include the actual file binary data in the subsequent scan request payload.
How long does the fileUrl remain valid for MCP scanning?
The fileUrl is a short-lived, one-time link generated by the A.I.G. server specifically for internal processing. While the exact expiration time is managed server-side within the Tencent/AI-Infra-Guard infrastructure, you should use the URL immediately after upload within the same session when submitting your mcp_scan task to ensure the file remains accessible.
Can I use a fileUrl from an external source instead of uploading?
No, the fileUrl must originate from the AI-Infra-Guard upload endpoint (/api/v1/app/taskapi/upload) to ensure the file is stored in the correct internal storage accessible to the MCP scanner. As implemented in the aig_client.py workflow, external URLs are not supported for security and access control reasons.
Where is the upload logic implemented in the AI-Infra-Guard codebase?
The upload logic resides in skills/aig-scanner/scripts/aig_client.py, specifically within the _upload_file() helper method. The high-level orchestration that connects uploading to MCP scanning is handled by cmd_scan_ai_tools() and _submit_and_poll() in the same file, demonstrating the complete flow from local file to scanned result within the Tencent/AI-Infra-Guard repository.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →