Official python implementation of UTCP. UTCP is an open standard that lets AI agents call any API directly, without extra middleware.
# Add to your Claude Code skills
git clone https://github.com/universal-tool-calling-protocol/python-utcpLast scanned: 5/10/2026
{
"issues": [],
"status": "PASSED",
"scannedAt": "2026-05-10T06:34:21.265Z",
"semgrepRan": false,
"npmAuditRan": true,
"pipAuditRan": true
}See how python-utcp compares with popular alternatives.
python-utcp is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by universal-tool-calling-protocol. Official python implementation of UTCP. UTCP is an open standard that lets AI agents call any API directly, without extra middleware. It has 653 GitHub stars.
Yes. python-utcp passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.
Clone the repository with "git clone https://github.com/universal-tool-calling-protocol/python-utcp" and add it to your Claude Code skills directory (see the Installation section above).
python-utcp is primarily written in Python. It is open-source under universal-tool-calling-protocol on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh python-utcp against similar tools.
No comments yet. Be the first to share your thoughts!
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
The Universal Tool Calling Protocol (UTCP) is a secure, scalable standard for defining and interacting with tools across a wide variety of communication protocols. UTCP 1.0.0 introduces a modular core with a plugin-based architecture, making it more extensible, testable, and easier to package.
In contrast to other protocols, UTCP places a strong emphasis on:
This repository contains the complete UTCP Python implementation:
core/ - Core utcp package with foundational components (README)plugins/communication_protocols/ - Protocol-specific plugins:
UTCP uses a modular architecture with a core library and protocol plugins:
utcp)The core/ directory contains the foundational components:
Tool, CallTemplate, UtcpManual, and AuthUtcpClient for tool interactionInstall the core library and any required protocol plugins:
# Install core + HTTP plugin (most common)
pip install utcp utcp-http
# Install additional plugins as needed
pip install utcp-cli utcp-mcp utcp-text
from utcp.utcp_client import UtcpClient
# Create client with HTTP API
client = await UtcpClient.create(config={
"manual_call_templates": [{
"name": "my_api",
"call_template_type": "http",
"url": "https://api.example.com/utcp"
}]
})
# Call a tool
result = await client.call_tool("my_api.get_data", {"id": "123"})
# Release the connections this client opened
await client.close()
A protocol plugin registers itself in one of two registries, and the choice decides who its state belongs to.
An instance registered with register_communication_protocol is shared by every UtcpClient in the process, and so is any state it keeps. That is right for state that is meant to be shared — a credential cache, a registry a decorator writes into — and wrong for state that belongs to one client. A shared instance lives as long as the process; no client closes it.
A protocol whose state must not be shared between clients registers a factory instead: live sessions or connections keyed per manual, child processes — anything one client's use or close() would take away from another. Each UtcpClient calls the factory once — at creation, or on first use if it was registered later — so each client gets its own instance, its own connections, and its own teardown on close():
from utcp.plugins.discovery import register_communication_protocol_factory
register_communication_protocol_factory("custom_type", CustomCommunicationProtocol)
This is what makes "a client per tenant / per user / per pooled connection" actually isolate them, rather than every client reaching into one shared instance. A type registered as a factory wins over the same type registered as an instance, so a plugin migrates by moving its registration from one call to the other and callers change nothing.
utcp-mcp and utcp-websocket register this way — MCP sessions (and, for stdio, child processes) and per-manual WebSocket connections belong to the client that opened them. utcp-http (HTTP, SSE, streamable HTTP) and utcp-gql stay shared instances: the only state they keep is an OAuth token cache, which is meant to be reused across clients; every request opens its own session.
client.close() closes the instances the client created — every one of them, even if one fails, after which the failures are raised together as UtcpProtocolCloseError. If UtcpClient.create fails after creating them, they are closed the same way before the error is re-raised.
UTCP supports multiple communication protocols through dedicated plugins:
| Plugin | Description | Status | Documentation |
|---|---|---|---|
utcp-http |
HTTP/REST APIs, SSE, streaming | ✅ Stable | HTTP Plugin README |
utcp-cli |
Command-line tools | ✅ Stable | CLI Plugin README |
utcp-mcp |
Model Context Protocol | ✅ Stable | MCP Plugin README |
utcp-text |
Local file-based tools | ✅ Stable | Text Plugin README |
utcp-websocket |
WebSocket real-time bidirectional communication | ✅ Stable | WebSocket Plugin README |
utcp-socket |
TCP/UDP protocols | 🚧 In Progress | Socket Plugin README |
utcp-gql |
GraphQL APIs | 🚧 In Progress | GraphQL Plugin README |
For development, you can install the packages in editable mode from the cloned repository:
# Clone the repository
git clone https://github.com/universal-tool-calling-protocol/python-utcp.git
cd python-utcp
# Install the core package in editable mode with dev dependencies
pip install -e "core[dev]"
# Install a specific protocol plugin in editable mode
pip install -e plugins/communication_protocols/http
Version 1.0.0 introduces several breaking changes. Follow these steps to migrate your project.
utcp core package and the specific protocol plugins you use (e.g., utcp-http, utcp-cli).UtcpClient is initialized with a UtcpClientConfig object, dict or a path to a JSON file containing the configuration.providers_file_path option is removed. Instead of a file path, you now provide a list of manual_call_templates directly within the UtcpClientConfig.provider has been replaced with call_template, and provider_type is now call_template_type.call_template_type http_stream has been renamed to streamable_http.from utcp.client.transport_interfaces.http_transport import HttpProvider becomes from utcp_http.http_call_template import HttpCallTemplate.TagAndDescriptionWordMatchStrategy. This is the new default and requires no changes unless you were implementing a custom strategy.manual_name.tool_name. The client handles this automatically.call_templates, are first namespaced with the name of the manual with the _ duplicated. So a key in a tool call template called API_KEY from the manual manual_1 would be converted to manual__1_API_KEY.config.json (Optional)
You can define a comprehensive client configuration in a JSON file. All of these fields are optional.
{
"variables": {
"openlibrary_URL": "https://openlibrary.org/static/openapi.json"
},
"load_variables_from": [
{
"variable_loader_type": "dotenv",
"env_file_path": ".env"