{"id":41654426,"url":"https://github.com/universal-tool-calling-protocol/typescript-utcp","last_synced_at":"2026-01-24T16:22:41.915Z","repository":{"id":303717960,"uuid":"1016349220","full_name":"universal-tool-calling-protocol/typescript-utcp","owner":"universal-tool-calling-protocol","description":"Official typescript implementation of UTCP. UTCP is an open standard that lets AI agents call any API directly, without extra middleware.","archived":false,"fork":false,"pushed_at":"2026-01-16T09:28:39.000Z","size":632,"stargazers_count":103,"open_issues_count":2,"forks_count":13,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-16T23:47:11.794Z","etag":null,"topics":["mcp","typescript","utcp"],"latest_commit_sha":null,"homepage":"https://www.utcp.io","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/universal-tool-calling-protocol.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-08T21:57:38.000Z","updated_at":"2026-01-03T20:28:18.000Z","dependencies_parsed_at":"2025-07-09T04:26:20.032Z","dependency_job_id":"830afa07-159c-4762-9058-2df160001758","html_url":"https://github.com/universal-tool-calling-protocol/typescript-utcp","commit_stats":null,"previous_names":["universal-tool-calling-protocol/typescript-utcp"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/universal-tool-calling-protocol/typescript-utcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/universal-tool-calling-protocol%2Ftypescript-utcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/universal-tool-calling-protocol%2Ftypescript-utcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/universal-tool-calling-protocol%2Ftypescript-utcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/universal-tool-calling-protocol%2Ftypescript-utcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/universal-tool-calling-protocol","download_url":"https://codeload.github.com/universal-tool-calling-protocol/typescript-utcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/universal-tool-calling-protocol%2Ftypescript-utcp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28731225,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T10:24:43.181Z","status":"ssl_error","status_checked_at":"2026-01-24T10:24:36.112Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mcp","typescript","utcp"],"created_at":"2026-01-24T16:22:40.465Z","updated_at":"2026-01-24T16:22:41.898Z","avatar_url":"https://github.com/universal-tool-calling-protocol.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Universal Tool Calling Protocol (UTCP) for TypeScript\n\n[![Follow Org](https://img.shields.io/github/followers/universal-tool-calling-protocol?label=Follow%20Org\u0026logo=github)](https://github.com/universal-tool-calling-protocol)\n[![NPM version](https://img.shields.io/npm/v/@utcp/sdk.svg)](https://www.npmjs.com/package/@utcp/sdk)\n[![License](https://img.shields.io/github/license/universal-tool-calling-protocol/python-utcp)](https://github.com/universal-tool-calling-protocol/typescript-utcp/blob/main/LICENSE)\n[![CDTM S23](https://img.shields.io/badge/CDTM-S23-0b84f3)](https://cdtm.com/)\n\n**The Universal Tool Calling Protocol (UTCP) is a secure and scalable standard for defining and interacting with tools across a wide variety of communication protocols. This repository contains the official TypeScript implementation, structured as a monorepo with a lean core and pluggable communication protocols.**\n\nUTCP offers a unified framework for integrating disparate tools and services, making them accessible through a consistent and well-defined interface. This TypeScript SDK provides a comprehensive toolkit for developers to leverage the full power of the UTCP standard in their applications.\n\n## Key Features\n\n*   **Automatic Plugin Registration**: The official plugins are automatically discovered and registered when you import the core client—no manual setup required. For other plugins, you will need to register them manually.\n*   **Scalability**: Designed to handle a large number of tools and providers without compromising performance.\n*   **Extensibility**: A pluggable architecture allows developers to easily add new communication protocols, tool storage mechanisms, and search strategies without modifying the core library.\n*   **Interoperability**: With a growing ecosystem of protocol plugins—including HTTP, MCP, Text, File, and CLI—UTCP can integrate with almost any existing service or infrastructure.\n*   **Code Execution Mode**: Execute TypeScript code with hierarchical access to tools, complete console output capture, and runtime interface introspection for powerful AI agent workflows.\n*   **Type Safety**: Built on well-defined TypeScript interfaces and runtime validation powered by Zod, making it robust and developer-friendly.\n*   **Secure Variable Management**: Namespace-isolated variables prevent leakage between manuals, with support for environment variables and .env files.\n\n![MCP vs. UTCP](https://github.com/user-attachments/assets/3cadfc19-8eea-4467-b606-66e580b89444)\n\n## Getting Started\n\n### Installation\n\nInstall UTCP packages from npm:\n\n```bash\n# Install core SDK and desired protocol plugins\nnpm install @utcp/sdk @utcp/http @utcp/mcp @utcp/text @utcp/file @utcp/code-mode\n\n# Optional: Add dotenv variable loader for Node.js\nnpm install @utcp/dotenv-loader\n\n# Or using bun\nbun add @utcp/sdk @utcp/http @utcp/mcp @utcp/text @utcp/file @utcp/code-mode\n```\n\n### For Development\n\nTo set up the monorepo for development:\n\n```bash\n# Clone the repository\ngit clone https://github.com/universal-tool-calling-protocol/typescript-utcp.git\ncd typescript-utcp\n\n# Install dependencies (requires bun)\nbun install\n\n# Build all packages\nbun run build\n```\n\n## Quick Start\n\n### Basic Usage\n\nPlugins are **automatically registered** when you import the UtcpClient—no manual registration needed!\n\n```typescript\nimport { UtcpClient } from '@utcp/sdk';\nimport { HttpCallTemplateSerializer } from '@utcp/http';\n\nasync function main() {\n  // Create client - plugins auto-register\n  const serializer = new HttpCallTemplateSerializer();\n  const githubTemplate = serializer.validateDict({\n    name: 'github_api',\n    call_template_type: 'http',\n    http_method: 'GET',\n    url: 'https://api.github.com/users/${username}',\n  });\n\n  const client = await UtcpClient.create(process.cwd(), {\n    manual_call_templates: [githubTemplate],\n    variables: {\n      // Namespace format: manual_name_VARIABLE\n      github__api_username: 'octocat'\n    }\n  });\n\n  // Search for tools\n  const tools = await client.searchTools('github user');\n  console.log('Found tools:', tools.map(t =\u003e t.name));\n\n  // Call a tool\n  const result = await client.callTool('github_api.get_user', {});\n  console.log('Result:', result);\n\n  await client.close();\n}\n\nmain().catch(console.error);\n```\n\n### Working with Multiple Protocols\n\n```typescript\nimport { UtcpClient } from '@utcp/sdk';\nimport { HttpCallTemplateSerializer } from '@utcp/http';\nimport { McpCallTemplateSerializer } from '@utcp/mcp';\nimport { FileCallTemplateSerializer } from '@utcp/file';\n\nasync function main() {\n  // Create serializers for each protocol\n  const httpSerializer = new HttpCallTemplateSerializer();\n  const mcpSerializer = new McpCallTemplateSerializer();\n  const fileSerializer = new FileCallTemplateSerializer();\n\n  // Validate and create call templates\n  const httpTemplate = httpSerializer.validateDict({\n    name: 'api_manual',\n    call_template_type: 'http',\n    http_method: 'GET',\n    url: 'https://api.example.com/data',\n    headers: {\n      'Authorization': 'Bearer ${API_KEY}'\n    }\n  });\n\n  const mcpTemplate = mcpSerializer.validateDict({\n    name: 'mcp_tools',\n    call_template_type: 'mcp',\n    config: {\n      mcpServers: {\n        my_mcp_server: {\n          transport: 'stdio',\n          command: 'node',\n          args: ['./mcp-server.js'],\n          cwd: './servers'\n        }\n      }\n    }\n  });\n\n  const fileTemplate = fileSerializer.validateDict({\n    name: 'local_tools',\n    call_template_type: 'file',\n    file_path: './config/tools.json'\n  });\n\n  const client = await UtcpClient.create(process.cwd(), {\n    variables: {\n      // Namespaced variables for security\n      api__manual_API_KEY: process.env.API_KEY || 'default-key',\n    },\n    load_variables_from: [\n      {\n        variable_loader_type: 'dotenv',\n        env_file_path: './.env'\n      }\n    ],\n    manual_call_templates: [\n      httpTemplate,  // HTTP API\n      mcpTemplate,   // MCP Server\n      fileTemplate   // Local file-based tools\n    ]\n  });\n\n  // Tools are namespaced: manual_name.tool_name\n  // For MCP: manual_name.server_name.tool_name\n  const allTools = await client.getTools();\n  console.log('Registered tools:', allTools.map(t =\u003e t.name));\n  \n  // Examples:\n  // - 'api_manual.get_data'\n  // - 'mcp_tools.my_mcp_server.echo'\n  // - 'local_tools.my_function'\n\n  await client.close();\n}\n```\n\n## API Reference\n\n### UtcpClient.create()\n\n```typescript\nstatic async create(\n  root_dir: string,\n  config: Partial\u003cUtcpClientConfig\u003e\n): Promise\u003cUtcpClient\u003e\n```\n\n**Parameters:**\n- `root_dir`: Base directory for resolving relative paths (usually `process.cwd()`)\n- `config`: Client configuration object\n\n**Configuration Options:**\n\n```typescript\ninterface UtcpClientConfig {\n  // Direct variable definitions (highest priority)\n  variables?: Record\u003cstring, string\u003e;\n  \n  // External variable loaders (e.g., .env files)\n  load_variables_from?: Array\u003c{\n    variable_loader_type: 'dotenv';\n    env_file_path: string;\n  }\u003e;\n  \n  // Manual call templates to register at startup\n  manual_call_templates?: CallTemplate[];\n  \n  // Tool repository configuration (defaults to in-memory)\n  tool_repository?: ConcurrentToolRepository;\n  \n  // Search strategy configuration (defaults to tag_and_description_word_match)\n  tool_search_strategy?: ToolSearchStrategy;\n  \n  // Post-processing configurations\n  post_processing?: ToolPostProcessor[];\n}\n```\n\n### Core Methods\n\n#### Search Tools\n```typescript\nasync searchTools(\n  query: string,\n  limit?: number,\n  anyOfTagsRequired?: string[]\n): Promise\u003cTool[]\u003e\n```\n\nSearches for tools matching the query. The search considers:\n- **Tool names** (highest priority)\n- **Tool tags**\n- **Tool descriptions**\n\n#### Call Tool\n```typescript\nasync callTool(\n  toolName: string,\n  args: Record\u003cstring, any\u003e\n): Promise\u003cany\u003e\n```\n\nExecutes a tool with the given arguments. Tool names follow these formats:\n- HTTP/Text/CLI: `manual_name.tool_name`\n- MCP: `manual_name.server_name.tool_name`\n\n#### Get Tools\n```typescript\nasync getTools(): Promise\u003cTool[]\u003e\nasync getTool(toolName: string): Promise\u003cTool | undefined\u003e\n```\n\nRetrieve all registered tools or get a specific tool by name.\n\n#### Register/Deregister Manuals\n```typescript\nasync registerManual(callTemplate: CallTemplate): Promise\u003cvoid\u003e\nasync deregisterManual(manualName: string): Promise\u003cboolean\u003e\n```\n\nDynamically add or remove tool manuals at runtime.\n\n## Variable Management\n\n### Variable Namespacing (Security Feature)\n\nVariables are **namespace-isolated** by manual name to prevent variable leakage between manuals:\n\n```typescript\n// For a manual named \"github_api\", variables are accessed as:\n// ${VARIABLE} -\u003e resolved from \"github__api_VARIABLE\"\n\nimport { HttpCallTemplateSerializer } from '@utcp/http';\n\nconst serializer = new HttpCallTemplateSerializer();\nconst githubTemplate = serializer.validateDict({\n  name: 'github_api',\n  call_template_type: 'http',\n  http_method: 'GET',\n  url: 'https://api.github.com/users',\n  headers: {\n    // Resolves to 'github__api_TOKEN' only\n    'Authorization': 'Bearer ${TOKEN}'\n  }\n});\n\nconst client = await UtcpClient.create(process.cwd(), {\n  variables: {\n    'github__api_TOKEN': 'github-token-123',\n    'slack__api_TOKEN': 'slack-token-456',\n  },\n  manual_call_templates: [githubTemplate]\n});\n```\n\n**Namespace transformation**: Manual name underscores become double underscores:\n- `github_api` → `github__api_`\n- `my-service` → `my_service_` (hyphens to underscores)\n\n### Variable Resolution Order\n\n1. **Client config variables** (highest priority)\n2. **Variable loaders** (e.g., .env files, in order)\n3. **Environment variables** (lowest priority)\n\nAll lookups use the namespaced key: `{namespace}_VARIABLE_NAME`.\n\n### Loading from .env Files\n\n```typescript\nconst client = await UtcpClient.create(process.cwd(), {\n  load_variables_from: [\n    {\n      variable_loader_type: 'dotenv',\n      env_file_path: './.env'\n    }\n  ]\n});\n```\n\n## Communication Protocols\n\n### HTTP Protocol\n\nSupports RESTful APIs with automatic OpenAPI specification conversion:\n\n```typescript\nimport { HttpCallTemplateSerializer } from '@utcp/http';\n\nconst serializer = new HttpCallTemplateSerializer();\nconst weatherTemplate = serializer.validateDict({\n  name: 'weather_api',\n  call_template_type: 'http',\n  http_method: 'GET',\n  url: 'https://api.weather.com/v1/forecast',\n  headers: {\n    'X-API-Key': '${API_KEY}'\n  },\n  // Optional: Basic, API Key, or OAuth2 authentication\n  auth: {\n    auth_type: 'api_key',\n    var_name: 'X-API-Key',\n    api_key_value: '${API_KEY}',\n    in: 'header'\n  }\n});\n```\n\n**Features:**\n- Path parameter substitution\n- Header and body templates\n- Multiple authentication methods\n- Automatic OpenAPI to UTCP conversion\n\n### MCP Protocol\n\nConnect to Model Context Protocol servers:\n\n```typescript\nimport { McpCallTemplateSerializer } from '@utcp/mcp';\n\nconst serializer = new McpCallTemplateSerializer();\nconst mcpTemplate = serializer.validateDict({\n  name: 'mcp_manual',\n  call_template_type: 'mcp',\n  config: {\n    mcpServers: {\n      server_name: {\n        transport: 'stdio', // or 'http'\n        command: 'bun',\n        args: ['run', './mcp-server.ts'],\n        cwd: './servers',\n        env: { DEBUG: 'true' }\n      }\n    }\n  }\n});\n```\n\n**Tool Naming:** `manual_name.server_name.tool_name`\n\n**Features:**\n- Stdio and HTTP transports\n- Persistent session management\n- Automatic retry on connection errors\n- Multiple servers per manual\n\n### Text Protocol\n\nHandle direct text/string content (browser-compatible):\n\n```typescript\nimport { TextCallTemplateSerializer } from '@utcp/text';\n\nconst serializer = new TextCallTemplateSerializer();\nconst textTemplate = serializer.validateDict({\n  name: 'inline_tools',\n  call_template_type: 'text',\n  content: JSON.stringify({\n    tools: [\n      // UTCP manual or OpenAPI spec as string\n    ]\n  })\n});\n```\n\n### File Protocol\n\nLoad tools from local JSON/YAML files or OpenAPI specs (Node.js only):\n\n```typescript\nimport { FileCallTemplateSerializer } from '@utcp/file';\n\nconst serializer = new FileCallTemplateSerializer();\nconst fileTemplate = serializer.validateDict({\n  name: 'local_tools',\n  call_template_type: 'file',\n  file_path: './config/tools.json'\n  // Supports: .json, .yaml, .yml, OpenAPI specs\n});\n```\n\n### CLI Protocol\n\nExecute command-line tools:\n\n```typescript\nimport { CliCallTemplateSerializer } from '@utcp/cli';\n\nconst serializer = new CliCallTemplateSerializer();\nconst cliTemplate = serializer.validateDict({\n  name: 'system_commands',\n  call_template_type: 'cli',\n  commands: [\n    {\n      command: 'git status'\n    }\n  ],\n  working_dir: './my-repo'\n});\n```\n\n## Code Execution Mode\n\nThe `@utcp/code-mode` package provides a powerful extension that allows executing TypeScript code with direct access to registered tools, perfect for AI agents and complex workflows:\n\n```typescript\nimport { CodeModeUtcpClient } from '@utcp/code-mode';\n\nasync function main() {\n  const client = await CodeModeUtcpClient.create();\n  \n  // Register your tools (same as regular UTCP)\n  await client.registerManual({\n    name: 'math_tools',\n    call_template_type: 'text',\n    content: '...' // Your tool definitions\n  });\n\n  // Execute TypeScript code with hierarchical tool access\n  const { result, logs } = await client.callToolChain(`\n    console.log('Starting calculation...');\n    \n    // Tools are organized by namespace: manual.tool\n    const sum = await math_tools.add({ a: 10, b: 20 });\n    console.log('Sum result:', sum.result);\n    \n    // Access TypeScript interfaces at runtime for introspection\n    const addInterface = __getToolInterface('math_tools.add');\n    console.log('Tool interface:', addInterface);\n    \n    // Chain multiple tool calls\n    const result = await math_tools.multiply({ \n      a: sum.result, \n      b: 2 \n    });\n    \n    return result;\n  `);\n  \n  console.log('Execution result:', result);\n  console.log('Console output:', logs);\n  // logs: ['Starting calculation...', 'Sum result: 30', 'Tool interface: ...']\n  \n  await client.close();\n}\n```\n\n### Code Mode Features\n\n- **Hierarchical Tool Access**: Tools organized by manual namespace (`manual.tool()`) preventing naming conflicts\n- **Console Output Capture**: All console output automatically captured and returned\n- **Runtime Interface Introspection**: Access TypeScript interface definitions during execution\n- **Type Safety**: Generated TypeScript interfaces for all tools with hierarchical namespaces\n- **Secure Execution**: VM-based sandboxed execution with timeout protection\n- **AI Agent Ready**: Built-in prompt template to guide AI agents on proper usage\n\n### Perfect for AI Agents\n\nThe `CodeModeUtcpClient.AGENT_PROMPT_TEMPLATE` provides comprehensive guidance for AI agents:\n\n```typescript\n// Add to your AI system prompt\nconst systemPrompt = `\n${CodeModeUtcpClient.AGENT_PROMPT_TEMPLATE}\n\nYour additional instructions...\n`;\n```\n\nThe template includes:\n- Tool discovery workflow\n- Interface introspection patterns\n- Best practices for hierarchical tool access\n- Error handling guidelines\n- Runtime context documentation\n\n## Monorepo Structure\n\n```\ntypescript-utcp/\n├── packages/\n│   ├── core/          # Core SDK with UtcpClient and interfaces\n│   ├── http/          # HTTP protocol plugin\n│   ├── mcp/           # MCP protocol plugin\n│   ├── text/          # Text/string content protocol plugin (browser-compatible)\n│   ├── file/          # File system protocol plugin (Node.js only)\n│   ├── code-mode/     # TypeScript code execution with hierarchical tool access\n│   ├── dotenv-loader/ # DotEnv variable loader plugin (Node.js only)\n│   ├── direct-call/   # Direct call protocol plugin\n│   └── cli/           # CLI protocol plugin\n├── tests/             # End-to-end integration tests\n└── README.md\n```\n\nEach package is independently published to npm:\n- `@utcp/sdk` - Core SDK library (required)\n- `@utcp/http` - HTTP protocol support\n- `@utcp/mcp` - MCP protocol support\n- `@utcp/text` - Direct text/string content (browser-compatible)\n- `@utcp/file` - File system operations (Node.js only)\n- `@utcp/code-mode` - TypeScript code execution with hierarchical tool access\n- `@utcp/dotenv-loader` - DotEnv variable loader (Node.js only)\n- `@utcp/direct-call` - Direct function call protocol\n- `@utcp/cli` - Command-line tools\n\n## Development \u0026 Testing\n\n### Build\n\n```bash\n# Build all packages\nbun run build\n\n# Clean and rebuild\nbun run rebuild\n```\n\n### Testing\n\n```bash\n# Run all tests\nbun test\n\n# Run specific test file\nbun test tests/utcp_client.test.ts\n```\n\n### Publishing\n\n```bash\n# Publish all packages\nbun run publish:all\n\n# Or publish individually\nbun run publish:core\nbun run publish:http\nbun run publish:mcp\n```\n\n## Advanced Features\n\n### Custom Tool Repositories\n\nImplement custom storage backends:\n\n```typescript\nimport { ConcurrentToolRepository } from '@utcp/sdk';\n\nclass RedisToolRepository implements ConcurrentToolRepository {\n  // Implement required methods\n  async getTools(): Promise\u003cTool[]\u003e { /* ... */ }\n  async getTool(name: string): Promise\u003cTool | undefined\u003e { /* ... */ }\n  // ... other methods\n}\n```\n\n### Custom Search Strategies\n\nImplement custom tool search algorithms:\n\n```typescript\nimport { ToolSearchStrategy } from '@utcp/sdk';\n\nclass SemanticSearchStrategy implements ToolSearchStrategy {\n  async searchTools(\n    repository: ConcurrentToolRepository,\n    query: string,\n    limit?: number\n  ): Promise\u003cTool[]\u003e {\n    // Custom semantic search implementation\n  }\n}\n```\n\n### Post-Processors\n\nTransform tool results:\n\n```typescript\nconst client = await UtcpClient.create(process.cwd(), {\n  post_processing: [\n    {\n      tool_post_processor_type: 'filter_dict',\n      allowed_keys: ['id', 'name', 'email']\n    },\n    {\n      tool_post_processor_type: 'limit_strings',\n      max_length: 1000\n    }\n  ]\n});\n```\n\n## Best Practices\n\n1. **Always call `client.close()`** to properly clean up resources\n2. **Use namespaced variables** for security and isolation\n3. **Leverage automatic plugin registration** - no manual setup needed\n4. **Use TypeScript types** from protocol packages for call templates\n5. **Handle tool call errors** appropriately in production\n6. **Test with integration tests** using the test patterns in `/tests`\n\n## License\n\nThis project is licensed under the Mozilla Public License Version 2.0. See the `LICENSE` file for details.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Code of Conduct\n\nThis project has adopted the Contributor Covenant Code of Conduct. For more information, see the [Code of Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funiversal-tool-calling-protocol%2Ftypescript-utcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funiversal-tool-calling-protocol%2Ftypescript-utcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funiversal-tool-calling-protocol%2Ftypescript-utcp/lists"}