Your agent,
ready to ship.
Any model. Built-in tools, memory, and MCP. Serve locally or publish to the Agentinc marketplace — all from one package.
pip install "agentinc-sdk[openai,serve]"
Installation
Install the SDK with pip or uv. Core depends only on Pydantic — extras add provider clients and the A2A server.
shell# Core (pydantic only) pip install agentinc-sdk # With OpenAI + A2A server pip install "agentinc-sdk[openai,serve]" # With Anthropic + A2A server pip install "agentinc-sdk[anthropic,serve]" # Everything pip install "agentinc-sdk[all]"
| Extra | Installs | Use for |
|---|---|---|
openai | openai>=1.0 | OpenAI + any OpenAI-compatible endpoint (DeepSeek, Groq, Ollama…) |
anthropic | anthropic>=0.25 | Anthropic Claude models |
gemini | google-genai>=1.0 | Google Gemini models |
memory | redis>=5.0 | Redis-backed session memory |
mcp | mcp>=1.0 | MCP server connections |
serve | fastapi, uvicorn, sse-starlette | A2A HTTP server |
all | all of the above | Full install |
ImportError with install instructions.
Agent Skill
Install the agentinc-sdk skill so your coding agent understands the Agent API and can help you build agents faster.
shellnpx skills add agentinc/sdk
Agent() with tools, MCP servers, or memory — it uses current SDK patterns.@tool correctly with proper type hints and JSON Schema generation.create_app() vs serve(), A2A protocol, and how to test with curl.Quickstart
Create an Agent, give it a model and a tool, then serve it over A2A.
quickstart.pyimport os from agentinc.sdk import Agent from agentinc.sdk.serve import serve def get_weather(city: str) -> str: """Gets the current weather for a city.""" return f"72°F and sunny in {city}" agent = Agent( role="You are a helpful assistant.", model={"model": "gpt-4o-mini", "api_key": os.environ["OPENAI_API_KEY"]}, tools=[get_weather], ) serve(agent, name="my-agent", port=8000)
shell# Start the server python quickstart.py # Call it curl -X POST http://localhost:8000 \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tasks/send","params":{"id":"t1","message":{"role":"user","parts":[{"type":"text","text":"What is the weather in Paris?"}]}}}'
Core Concepts
The SDK defines the contract between your agent code and the Agentinc platform.
run() for framework integrations that manage their own LLM calls.@tool or pass plain functions to tools=.ToolProtocol with auto-generated JSON schema from type hints and docstrings.Agent(tools=[...]) are auto-wrapped — @tool is optional. Use it when you want an explicit name or description.
Agent
The main developer-facing class. Implements AgentProtocol — pass it directly to serve().
Wires together a provider, tool dispatch loop, optional Redis memory, and optional MCP connections. The tool loop is built-in: the agent calls tools, feeds results back to the LLM, and repeats until a text response is produced.
pythonAgent( role: str, # system prompt / persona model: ModelConfig, # provider + credentials dict tools: list[Callable] = [], # plain functions — auto-wrapped mcps: list[MCPConfig] = [], # MCP server connections memory: MemoryConfig | None = None, # Redis-backed session memory context: str | None = None, # extra context appended to system prompt data: DataConfig | None = None, # RAG config (reserved) )
ModelConfig
Provider credentials as a plain dict. Provider auto-detected from model name prefix. When base_url is set, the OpenAI-compatible provider is used regardless of model name.
python# OpenAI {"model": "gpt-4o-mini", "api_key": "sk-..."} # Anthropic {"model": "claude-sonnet-4-6", "api_key": "sk-ant-..."} # Google Gemini {"model": "gemini-1.5-pro", "api_key": "..."} # Any OpenAI-compatible endpoint (DeepSeek, Groq, Ollama, …) {"model": "deepseek-chat", "api_key": "sk-...", "base_url": "https://api.deepseek.com"}
| Model prefix | Auto-detected provider | Required extra |
|---|---|---|
gpt-*, o1-*, o3-* | OpenAI | [openai] |
claude-* | Anthropic | [anthropic] |
gemini-* | Google Gemini | [gemini] |
any + base_url | OpenAI-compatible | [openai] |
MemoryConfig
Redis-backed session memory. History is loaded at the start of each run() and saved at the end. Requires pip install 'agentinc-sdk[memory]'.
python{ "type": "redis", "connection": "redis://localhost:6379/0", "user": "optional", "password": "optional", }
Session ID from input.metadata["session_id"]. Falls back to a per-request UUID when absent. History stored with a 24-hour TTL.
shell — passing session_idcurl -X POST http://localhost:8000 \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tasks/send","params":{"id":"t1","metadata":{"session_id":"user-123"},"message":{"role":"user","parts":[{"type":"text","text":"My name is Alice"}]}}}'
MCPConfig
Connect to MCP servers. Tool schemas are fetched on the first run() call and merged with local tools. Requires pip install 'agentinc-sdk[mcp]'.
python# stdio — spawns a subprocess { "type": "stdio", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"], } # SSE — connects to a running HTTP server { "type": "sse", "url": "http://localhost:3001/sse", }
AgentProtocol
The universal agent contract. Use this for framework integrations that manage their own LLM calls. Agent already implements it.
Any object with a matching run method satisfies the protocol. No inheritance needed.
protocol.py@runtime_checkable class AgentProtocol(Protocol): def run(self, input: AgentInput) -> AsyncIterator[AgentOutput]: ...
Direct implementation
my_agent.pyfrom agentinc.sdk import AgentInput, AgentOutput, AgentProtocol from agentinc.sdk.serve import serve class MyAgent: async def run(self, input: AgentInput): yield AgentOutput(content=f"Hello! You said: {input.message}", done=True) assert isinstance(MyAgent(), AgentProtocol) # passes serve(MyAgent(), name="my-agent", port=8000)
ToolProtocol
The contract for tools the agent can invoke.
Any object with schema() and call() satisfies this protocol.
protocol.py@runtime_checkable class ToolProtocol(Protocol): def schema(self) -> ToolSchema: ... async def call(self, tool_call: ToolCall) -> str: ...
Schemas
Pydantic models forming the data contract between agents, tools, and the platform.
Input to every agent invocation.
| Field | Type | Default | Description |
|---|---|---|---|
message | str | required | The user's message |
history | list[Message] | [] | Conversation history |
tool_schemas | list[ToolSchema] | [] | Caller-supplied tool schemas |
metadata | dict[str, Any] | {} | session_id key used by Redis memory |
A single chunk yielded by an agent's run().
| Field | Type | Default | Description |
|---|---|---|---|
content | str | None | None | Text content of this chunk |
tool_calls | list[ToolCall] | [] | Tool calls the agent wants to make |
done | bool | False | Whether this is the final chunk |
metadata | dict[str, Any] | {} | Arbitrary output metadata |
@tool Decorator
Turn any function into a ToolProtocol with one line. Schema auto-generated from type hints and docstring.
Returns a ToolWrapper. Works with sync and async functions.
pythonfrom agentinc.sdk import tool # Bare — schema from type hints + docstring @tool async def search(query: str, limit: int = 10) -> str: """Searches the web for a query.""" return f"Results for {query}" # With explicit name / description @tool(name="add", description="Adds two numbers") def add_numbers(a: float, b: float) -> str: return str(a + b)
Type mappings
| Python | JSON Schema |
|---|---|
str | {"type": "string"} |
int | {"type": "integer"} |
float | {"type": "number"} |
bool | {"type": "boolean"} |
list[str] | {"type": "array", "items": {"type": "string"}} |
dict | {"type": "object"} |
ToolWrapper
The object returned by @tool. Satisfies ToolProtocol — call directly or via a ToolCall.
Wraps any sync or async callable with a JSON schema and ToolProtocol interface.
pythonfrom agentinc.sdk import tool, ToolCall @tool def greet(name: str) -> str: """Says hello.""" return f"Hello, {name}!" # Via ToolCall (how the platform dispatches) result = await greet.call(ToolCall(id="1", name="greet", arguments={"name": "World"})) # Direct call result = await greet(name="World")
RawAdapter ⚠ Deprecated
Kept for backward compatibility. Emits DeprecationWarning on instantiation. Will be removed in v0.3.
Wraps any callable as AgentProtocol.run(). Migrate to Agent() or implement AgentProtocol directly.
Agent(role=..., model=..., tools=[...]). For framework integrations, implement AgentProtocol directly.
A2A Server
Serve any AgentProtocol as an A2A-compliant HTTP endpoint. Requires [serve] extra.
| Method | Path | Description |
|---|---|---|
GET | /.well-known/agent.json | Agent card |
POST | / | JSON-RPC 2.0 (tasks/send, tasks/sendSubscribe) |
create_app()
Returns a FastAPI app for custom ASGI deployments.
pythonfrom agentinc.sdk import Agent from agentinc.sdk.serve import create_app app = create_app( Agent(role="You are helpful.", model={"model": "gpt-4o-mini", "api_key": "sk-..."}), name="my-agent", ) # uvicorn myfile:app --port 8000
serve()
Blocking one-liner. Calls uvicorn internally. Best for scripts and local dev.
| Parameter | Type | Default | Description |
|---|---|---|---|
agent | AgentProtocol | required | The agent to serve |
name | str | "agent" | Agent name |
description | str | "" | Agent description |
host | str | "0.0.0.0" | Bind address |
port | int | 8000 | Bind port |
Example: OpenAI Agent
Minimal Agent with a tool using an OpenAI model.
openai_agent.pyimport os from agentinc.sdk import Agent from agentinc.sdk.serve import serve def get_weather(city: str) -> str: """Gets the current weather for a city.""" return f"72°F and sunny in {city}" agent = Agent( role="You are a helpful assistant.", model={"model": "gpt-4o-mini", "api_key": os.environ["OPENAI_API_KEY"]}, tools=[get_weather], ) serve(agent, name="openai-agent", port=8000)
Example: Anthropic Agent
Claude-powered agent — provider auto-detected from the claude- prefix.
anthropic_agent.pyimport os from agentinc.sdk import Agent from agentinc.sdk.serve import serve def lookup(topic: str) -> str: """Looks up a fact in the knowledge base.""" return f"Here's what we know about {topic}: it's fascinating." agent = Agent( role="You are a helpful assistant.", model={"model": "claude-sonnet-4-6", "api_key": os.environ["ANTHROPIC_API_KEY"]}, tools=[lookup], ) serve(agent, name="anthropic-agent", port=8002)
Example: Session Memory
Persistent multi-turn conversations backed by Redis.
memory_agent.pyimport os from agentinc.sdk import Agent from agentinc.sdk.serve import serve agent = Agent( role="You are a friendly assistant with a long memory.", model={"model": "gpt-4o-mini", "api_key": os.environ["OPENAI_API_KEY"]}, memory={ "type": "redis", "connection": os.environ.get("REDIS_URL", "redis://localhost:6379/0"), "password": os.environ.get("REDIS_PASSWORD"), }, ) serve(agent, name="memory-agent", port=8000)
shell — two-turn session test# Turn 1 curl -X POST http://localhost:8000 \ -d '{"jsonrpc":"2.0","id":1,"method":"tasks/send","params":{"id":"t1","metadata":{"session_id":"demo"},"message":{"role":"user","parts":[{"type":"text","text":"My name is Alice"}]}}}' # Turn 2 — agent recalls the name curl -X POST http://localhost:8000 \ -d '{"jsonrpc":"2.0","id":2,"method":"tasks/send","params":{"id":"t2","metadata":{"session_id":"demo"},"message":{"role":"user","parts":[{"type":"text","text":"What is my name?"}]}}}'
Example: MCP Server
Connect to an MCP server. Tool schemas are fetched on first call and merged with local tools.
mcp_agent.pyimport os from agentinc.sdk import Agent from agentinc.sdk.serve import serve def read_file(path: str) -> str: """Reads a local file.""" with open(path) as f: return f.read() agent = Agent( role="You are a helpful file assistant.", model={"model": "gpt-4o-mini", "api_key": os.environ["OPENAI_API_KEY"]}, tools=[read_file], # local tools mcps=[{ # MCP tools — discovered on first run() "type": "stdio", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"], }], ) serve(agent, name="mcp-agent", port=8000)
Example: LangChain Agent
LangChain manages its own LLM calls — implement AgentProtocol directly.
langchain_agent.pyfrom langchain_core.messages import HumanMessage, AIMessage, SystemMessage from langchain_core.tools import tool as lc_tool from langchain_openai import ChatOpenAI from agentinc.sdk import AgentInput, AgentOutput from agentinc.sdk.serve import serve @lc_tool def calculator(expression: str) -> str: """Evaluates a math expression.""" return str(eval(expression)) llm = ChatOpenAI(model="gpt-4o-mini").bind_tools([calculator]) class LangChainAgent: async def run(self, input: AgentInput): messages = [SystemMessage(content="You are a helpful assistant.")] for msg in input.history: messages.append( HumanMessage(content=msg.content) if msg.role == "user" else AIMessage(content=msg.content or "") ) messages.append(HumanMessage(content=input.message)) response = await llm.ainvoke(messages) if response.tool_calls: yield AgentOutput( tool_calls=[{"id": tc["id"], "name": tc["name"], "arguments": tc["args"]} for tc in response.tool_calls], done=False, ) else: yield AgentOutput(content=response.content, done=True) serve(LangChainAgent(), name="langchain-agent", port=8003)
Example: CrewAI Agent
CrewAI manages its own orchestration — implement AgentProtocol directly and wrap the blocking call.
crewai_agent.pyimport asyncio from crewai import Agent as CrewAgent, Crew, Task from agentinc.sdk import AgentInput, AgentOutput from agentinc.sdk.serve import serve researcher = CrewAgent( role="Senior Research Analyst", goal="Provide thorough research on any topic", backstory="You are an experienced research analyst.", verbose=False, ) class CrewAIAgent: async def run(self, input: AgentInput): task = Task(description=input.message, expected_output="Clear analysis", agent=researcher) crew = Crew(agents=[researcher], tasks=[task], verbose=False) # kickoff() is synchronous — wrap to avoid blocking the event loop result = await asyncio.to_thread(crew.kickoff) yield AgentOutput(content=str(result), done=True) serve(CrewAIAgent(), name="crewai-agent", port=8004)
Ship to the Marketplace
Once your agent works locally, publish it to the Agentinc marketplace so tenants can discover and deploy it into their own isolated namespaces.
serve() and verify your agent responds correctly over A2A before publishing.agent.json in your project with name, description, version, and entry point.agentinc publish to bundle and upload your agent to the marketplace registry.agent.json manifest
agent.json{ "name": "my-agent", "version": "1.0.0", "description": "A helpful assistant with tool support", "entrypoint": "agent.py", "runtime": "python3.12", "capabilities": { "streaming": true, "tools": true, "memory": false } }
Publish
shell# Login to the Agentinc registry agentinc login # Publish from your project directory agentinc publish # Publish a specific version agentinc publish --version 1.2.0 # List your published agents agentinc agents list
Entry point structure
Your entrypoint file must expose a top-level variable named agent that satisfies AgentProtocol.
agent.py# agent.py — this file is what the platform imports import os from agentinc.sdk import Agent def get_weather(city: str) -> str: """Gets the current weather for a city.""" return f"72°F and sunny in {city}" # The platform reads this variable — name must be "agent" agent = Agent( role="You are a helpful weather assistant.", model={"model": "gpt-4o-mini", "api_key": os.environ["OPENAI_API_KEY"]}, tools=[get_weather], ) # Optional: run locally for testing if __name__ == "__main__": from agentinc.sdk.serve import serve serve(agent, name="weather-agent", port=8000)
os.environ as shown above.
All Exports
Everything exported from agentinc.sdk.
pythonfrom agentinc.sdk import ( # Core Agent, # Main class — declare and run agents AgentProtocol, # Protocol — implement run() for custom integrations ToolProtocol, # Protocol — implement schema() + call() AgentFactory, # Type alias — callable returning AgentProtocol # Schemas AgentInput, # Model — agent invocation input AgentOutput, # Model — single output chunk Message, # Model — conversation history entry ToolCall, # Model — tool invocation request ToolSchema, # Model — tool JSON schema # Config TypedDicts ModelConfig, # Provider + credentials MemoryConfig, # Redis memory config MCPConfig, # MCP server connection config DataConfig, # RAG config (reserved) # Tools ToolWrapper, # Class — wraps callable as ToolProtocol tool, # Decorator — function → ToolWrapper # Deprecated RawAdapter, # DEPRECATED — use Agent() instead ) # A2A serve module (requires [serve] extra) from agentinc.sdk.serve import create_app, serve