Documentation Index Fetch the complete documentation index at: https://docs.hellofriday.ai/llms.txt
Use this file to discover all available pages before exploring further.
Declare required MCP servers in the @agent decorator:
from friday_agent_sdk import agent, ok
@agent (
id = "github-helper" ,
version = "1.0.0" ,
description = "Uses GitHub MCP server" ,
mcp = {
"github" : {
"transport" : {
"type" : "stdio" ,
"command" : "npx" ,
"args" : [ "-y" , "@modelcontextprotocol/server-github" ],
}
}
},
)
def execute ( prompt , ctx ):
...
tools = ctx.tools.list()
for tool in tools:
print ( f " { tool.name } : { tool.description } " )
print ( f " Schema: { tool.input_schema } " )
Returns a list of ToolDefinition objects:
tool.name # Tool identifier
tool.description # Human-readable description
tool.input_schema # JSON Schema for arguments
result = ctx.tools.call(
"search_issues" ,
{
"query" : "is:open label:bug" ,
"repo" : "my-org/my-repo" ,
},
)
# result is a dict parsed from the tool's JSON output
return ok({ "issues" : result[ "issues" ]})
Error Handling
Tool failures raise ToolCallError:
from friday_agent_sdk import ToolCallError, agent, err, ok
@agent ( id = "safe-caller" , version = "1.0.0" , description = "Handles tool errors" )
def execute ( prompt , ctx ):
try :
result = ctx.tools.call( "risky_operation" , { "data" : prompt})
except ToolCallError as e:
return err( f "Tool failed: { e } " )
return ok({ "result" : result})
Real Example: Time Operations
@agent (
id = "time-agent" ,
version = "1.0.0" ,
description = "Time conversion agent" ,
mcp = {
"time" : {
"transport" : {
"type" : "stdio" ,
"command" : "uvx" ,
"args" : [ "mcp-server-time" , "--local-timezone" , "UTC" ],
}
}
},
)
def execute ( prompt , ctx ):
# Get current time in Tokyo
result = ctx.tools.call(
"get_current_time" ,
{ "timezone" : "Asia/Tokyo" },
)
# Convert time
converted = ctx.tools.call(
"convert_time" ,
{
"source_timezone" : "UTC" ,
"time" : "14:30" ,
"target_timezone" : "America/New_York" ,
},
)
return ok({
"tokyo_time" : result,
"converted" : converted,
})
Multiple MCP Servers
@agent (
id = "multi-tool" ,
version = "1.0.0" ,
description = "Uses GitHub and database tools" ,
mcp = {
"github" : {
"transport" : {
"type" : "stdio" ,
"command" : "npx" ,
"args" : [ "-y" , "@modelcontextprotocol/server-github" ],
}
},
"postgres" : {
"transport" : {
"type" : "stdio" ,
"command" : "npx" ,
"args" : [ "-y" , "@modelcontextprotocol/server-postgres" ],
"env" : {
"DATABASE_URL" : "postgresql://..." ,
},
}
}
},
)
def execute ( prompt , ctx ):
tools = ctx.tools.list()
# Tools from both servers are available
github_tools = [t for t in tools if "github" in t.name]
db_tools = [t for t in tools if "postgres" in t.name]
...
Environment Variables in MCP
Pass environment variables directly to MCP server processes:
mcp = {
"github" : {
"transport" : {
"type" : "stdio" ,
"command" : "npx" ,
"args" : [ "-y" , "@modelcontextprotocol/server-github" ],
"env" : {
"GITHUB_TOKEN" : "your-github-token" ,
}
}
}
}
To declare environment variables your agent code accesses via ctx.env, use the environment decorator field:
environment = {
"required" : [
{ "name" : "GITHUB_TOKEN" , "description" : "GitHub API token" },
]
}
Stdio vs SSE Transport
Currently only stdio transport is supported. sse (Server-Sent Events) is planned.
# Chain multiple tool calls
tools = ctx.tools.list()
# Find relevant tool by name
search_tool = next ((t for t in tools if t.name == "search_issues" ), None )
if not search_tool:
return err( "search_issues tool not available" )
# Search
issues = ctx.tools.call( "search_issues" , { "query" : prompt})
# For each issue, get details
for issue in issues[ "issues" ][: 5 ]:
details = ctx.tools.call(
"get_issue" ,
{ "owner" : "my-org" , "repo" : "my-repo" , "issue_number" : issue[ "number" ]},
)
# Process details...
API Reference: ctx.tools Full tools capability API reference
MCP Specification Official MCP protocol documentation
MCP Servers Registry Browse available MCP servers