- [Quick Start](#quick-start)
Basic PCP Usage
Table of Contents
- Quick Start
- Shell Commands
- HTTP Requests
- Filesystem Controls
- Request Anatomy
- Handling Results
- Troubleshooting
Quick Start
PCP becomes active as soon as a pipe has a populated PcpContext and you enable tool use in your
system prompt. This minimal example exposes a single read-only shell command:
import com.TTT.PipeContextProtocol.PcpContext
import com.TTT.PipeContextProtocol.StdioContextOptions
import com.TTT.PipeContextProtocol.Permissions
fun minimalContext(): PcpContext = PcpContext().apply {
addStdioOption(
StdioContextOptions().apply {
command = "ls"
description = "List files in the working directory"
permissions.add(Permissions.Read)
timeoutMs = 3_000
}
)
}
Attach it to a pipe:
val pipe = myBedrockPipe()
pipe.setPcPContext(minimalContext())
pipe.setSystemPrompt("You may use PCP tools to inspect the workspace.")
Shell Commands
Command allowlists
Limit arguments the model may pass by supplying an allowlist. The executor enforces this list for
both default arguments (args) and runtime arguments supplied via argumentsOrFunctionParams:
val gitStatus = StdioContextOptions().apply {
command = "git"
description = "Read-only Git operations"
args.addAll(listOf("status", "diff", "log"))
permissions.addAll(listOf(Permissions.Read, Permissions.Execute))
}
If argumentsOrFunctionParams contains push, validation fails with Argument 'push' is not in the allowed arguments list.
Execution modes
Interactive workflows require persistent sessions:
val shell = StdioContextOptions().apply {
command = "bash"
executionMode = StdioExecutionMode.INTERACTIVE
keepSessionAlive = true
bufferPersistence = true
permissions.addAll(listOf(Permissions.Read, Permissions.Write, Permissions.Execute))
}
To reconnect later, pass the returned sessionId in a CONNECT request.
HTTP Requests
Configure an endpoint with explicit method and host allowlists so
HttpSecurityManager passes validation:
import com.TTT.PipeContextProtocol.HttpContextOptions
val issues = HttpContextOptions().apply {
baseUrl = "https://api.github.com"
endpoint = "/repos/octocat/Hello-World/issues"
method = "GET"
allowedMethods.add("GET")
allowedHosts.add("api.github.com")
permissions.add(Permissions.Read)
headers["Accept"] = "application/vnd.github+json"
timeoutMs = 10_000
description = "List public issues"
}
Attach the option with context.addHttpOption(issues) and ensure the pipe’s PCP context also
includes any required auth tokens inside authType/authCredentials if needed.
Filesystem Controls
Restrictions live on the enclosing PcpContext and apply to every transport. If the model submits a
path outside the allowlist, the command is rejected before execution.
val context = minimalContext().apply {
allowedDirectoryPaths.addAll(listOf(
"/home/app/project",
"/tmp"
))
forbiddenDirectoryPaths.add("/home/app/project/secret")
allowedFiles.add("/home/app/project/config.yaml")
forbiddenFiles.add("/home/app/project/.env")
}
Request Anatomy
A typical stdio request produced by the LLM looks like this:
{
"requests": [
{
"stdioContextOptions": {
"command": "ls",
"executionMode": "ONE_SHOT",
"timeoutMs": 3000
},
"argumentsOrFunctionParams": ["-la", "/home/app/project"],
"httpContextOptions": {},
"tPipeContextOptions": {},
"pythonContextOptions": {}
}
]
}
PcpResponseParser.extractPcpRequests can pull this structure from raw LLM output and validate it
with PcpResponseParser.validatePcpRequest before dispatch.
Handling Results
Each executor returns a PcpRequestResult:
runBlocking {
when (val result = dispatcher.executeRequest(request, context)) {
else -> if (result.success) {
println(result.output)
} else {
println("PCP error (${result.transport}): ${result.error}")
}
}
}
For batch executions, PcpExecutionResult.errors collects any failures while preserving successful
outputs.
Troubleshooting
- “Command … exceeds maximum allowed level”: grant additional
Permissionsor reclassify the command viaCommandSecurityManager.setCommandClassification. - “Host … is not in allowed hosts list”: add the host to
HttpContextOptions.allowedHostsor disable host enforcement by settingHttpSecurityConfig(requireExplicitHosts = false). - “Python script is required”: ensure the request populates
argumentsOrFunctionParamswith the script content when targeting the Python executor. - Timeout errors: increase
timeoutMson the relevant context option. The executor terminates processes when the limit is reached.
With these building blocks you can progressively open more capabilities while keeping the model inside a controlled sandbox. For deeper features—Python execution, native functions, and security policies—see Intermediate PCP Features.
Next Steps
- Intermediate PCP Features - Continue with Python, native functions, and deeper security.