56a1cd0a6c1003ebc3ce4a099d6f02f77eac8205
fast-agent's MCPAgentClientSession.send_request catches every downstream
transport exception, logs the one-line 'send_request failed: <str(e)>'
WITHOUT exc_info=True, then re-raises. The exception then propagates
up to the agent loop where its message is serialised as the tool result
string ('object NoneType can't be used in an await expression' being
the canonical symptom) and the traceback is lost forever.
Wrap send_request so Pallas emits logger.exception() with the full
stack against the 'pallas.forward.trace' logger before re-raising.
No behavioural change — we re-raise the same exception; we just get
one extra log record with the frames attached, which pallas.log now
preserves thanks to the _JSONFormatter traceback field.
This will surface the real origin of the NoneType-await that's
currently being served as Harper's mnemosyne tool result even though
Mnemosyne itself returns 200 OK.
Pallas — FastAgent MCP Bridge
Pallas is the generic runtime that turns fast-agent agent definitions into StreamableHTTP MCP servers.
It is completely deployment-agnostic: all environment-specific values (agent names, ports, hosts, model) live in the calling project's agents.yaml and fastagent.config.yaml.
Installation
pip install git+ssh://git@git.helu.ca:22022/r/pallas.git
Or as a project dependency in pyproject.toml:
dependencies = [
"pallas-mcp @ git+ssh://git@git.helu.ca:22022/r/pallas.git",
]
Usage
Pallas reads configuration from the working directory at runtime.
my-project/
├── agents/
│ ├── __init__.py
│ └── jarvis.py # FastAgent definitions
├── agents.yaml # Deployment topology
├── fastagent.config.yaml # FastAgent + model config
└── fastagent.secrets.yaml # API keys (gitignored)
Run from your project root:
pallas # start all agents + registry
pallas --agent jarvis # start a single agent
Or via python -m:
python -m pallas.server
agents.yaml format
name: my-project # used in log prefixes and registry names
version: "1.0.0"
host: my-host.example.com # hostname for registry URLs
namespace: com.example.my-project
registry_port: 8200
agents:
jarvis:
module: agents.jarvis # importable Python module path
port: 8201
title: Jarvis
description: "My assistant agent"
depends_on: [research] # optional: start these first
research:
module: agents.research
port: 8250
title: Research Agent
description: "Web search and knowledge graph"
fastagent.config.yaml extensions
Pallas reads two extra keys beyond the standard fast-agent config:
default_model: openai.my-custom-model-name
# Explicit capability declarations — avoids brittle name-regex heuristics
model_capabilities:
vision: false
context_window: 200000
max_output_tokens: 32000
Capabilities are published in the registry and used to register unknown models
with fast-agent's ModelDatabase.
Environment variable
| Variable | Default | Purpose |
|---|---|---|
PALLAS_AGENTS_CONFIG |
agents.yaml |
Override path to deployment config |
What Pallas provides
| Module | Purpose |
|---|---|
pallas.server |
CLI entry point and agent orchestration |
pallas.registry |
GET /.well-known/mcp/server.json registry server |
pallas.multimodal_server |
MultimodalAgentMCPServer — AgentMCPServer subclass with image support |
pallas.health |
LLM preflight validation + get_health MCP tool |
Description
FastAgent MCP Bridge — generic runtime for serving FastAgent agents over StreamableHTTP
Languages
Python
100%