StackOne
StackOne
이 문서에서는 StackOne capability를 소개해요. 에이전트가 사용자의 연결된 비즈니스 애플리케이션(BambooHR, Salesforce, Zendesk 등) 중 하나와 작업해야 할 때 사용해요. 각 인스턴스는 하나의 연결된 계정 범위로 지정되며, 이는 StackOne과 프로바이더 사이의 하나의 인증된 연결이에요.
출처: 문서
본문
사용자의 연결된 비즈니스 애플리케이션(BambooHR, Salesforce, Zendesk 등) 중 하나로 에이전트가 작업해야 할 때 StackOne을 사용하세요. 각 인스턴스는 하나의 연결된 계정 범위로 지정되며, 이는 StackOne과 프로바이더 사이의 하나의 인증된 연결이에요.
Pydantic AI Harness가 0.x 릴리스인 동안에는 minor 릴리스 사이에 API가 바뀔 수 있어요. 그럴 때는 deprecation 경고와 릴리스 노트 마이그레이션 안내가 (당신이나 당신의 에이전트에게) 정확히 업그레이드 방법을 알려줘요. 버전 정책을 참고하세요.
Before you start
StackOne 문서를 따라:
- 커넥터를 구성하고 계정을 연결하세요. 첫 테스트에서는 필요한 읽기 액션만 활성화하세요.
- StackOne 대시보드에서 연결된 계정 ID를 복사하세요.
- 액션을 실행할 수 있는 StackOne API 키를 만드세요.
또한 에이전트가 사용하는 모델의 API 키도 필요해요.
Installation
Terminal
pip install "pydantic-ai-harness[stackone]" "pydantic-ai-slim[openai,spec]"
Terminal
uv add "pydantic-ai-harness[stackone]" "pydantic-ai-slim[openai,spec]"
openai와 spec extra가 아래의 모델 및 agent-spec 예시를 지원해요. 다른 모델 프로바이더에는 해당 프로바이더 extra를 대신 설치하세요.
예시를 실행할 셸에서 자격 증명을 설정하세요:
Terminal
export STACKONE_API_KEY='your-stackone-api-key'
export STACKONE_ACCOUNT_ID='your-linked-account-id'
export OPENAI_API_KEY='your-openai-api-key'
StackOne은 STACKONE_API_KEY를 자동으로 읽어요. 예시는 계정 ID가 하드코딩되지 않도록 STACKONE_ACCOUNT_ID를 명시적으로 읽어요. api_key=로 직접 전달할 수도 있지만, 비밀을 소스 제어에 두지 마세요.
Run your first agent
import os
from pydantic_ai import Agent
from pydantic_ai_harness import StackOne
agent = Agent(
'openai:gpt-5',
capabilities=[
StackOne(account_id=os.environ['STACKONE_ACCOUNT_ID']),
],
)
result = agent.run_sync('List the first 5 employees')
print(result.output)
기본적으로 모델은 두 개의 도구를 받아요. 요청과 일치하는 액션을 검색한 다음, 반환된 액션 ID를 실행해요. 최종 출력은 연결된 프로바이더와 그 데이터에 따라 달라요.
Control available actions
StackOne은 연결된 계정에 대해 어떤 액션이 활성화되는지 제어해요. 그 구성을 기본 접근 제어로 취급하세요.
모델이 보는 도구도 제한하고 싶을 때 actions를 사용하세요. 패턴은 Python fnmatch 구문을 사용하며, *는 와일드카드예요. 대소문자를 무시하고 전체 {connector}_{action}_{entity} 도구 이름을 매칭해요:
from pydantic_ai_harness import StackOne
StackOne(account_id='your-linked-account-id', actions=['*_list_*']) # All matching list tools
StackOne(account_id='your-linked-account-id', actions=['workday_get_worker']) # One exact tool
actions를 전달하면 individual 모드를 자동으로 선택해요. actions를 tool_mode='search_execute'와 명시적으로 결합하면 그 모드가 검색·실행 도구만 등록하므로 오류가 발생해요.
Choose a tool mode
Mode
What the model receives
Use it when
search_execute
두 도구: 액션 검색 후 ID로 실행
계정에 활성화된 액션이 많을 때. actions를 생략할 때의 기본값이에요.
individual
활성화된 액션마다 도구 하나와 스키마 하나
정확한 액션을 선택하거나 도구별 동작을 추가해야 할 때. actions를 전달하면 이 모드를 선택해요.
search_execute 모드에서는 액션 ID가 런타임에 검색 도구에 의해 반환되며 추측하면 안 돼요. individual 모드에서는 모든 선택된 도구 스키마가 모델로 전송되므로, 큰 액션 집합을 actions로 필터링하세요.
StackOne 도구가 필요할 때까지 모델 컨텍스트 밖에 두려면 defer_loading=True를 전달하세요. capability가 요청 시 로드되려면 id가 필요하며, 연결된 계정에서 파생해요 — StackOne(account_id='45320')은 stackone-45320 — 그래서 한 에이전트가 각 계정을 이름지지 않고도 여러 계정에 도달할 수 있어요:
from pydantic_ai_harness import StackOne
StackOne(account_id='your-linked-account-id', defer_loading=True)
같은 계정의 두 capability는 그 id를 공유하고 에이전트 구성에서 거부돼요. 그것이 원하는 것이에요. 하나의 연결된 계정은 하나의 연결이니까요. 파생된 것을 재정의해야 한다면 명시적 id=를 전달하세요.
Two accounts on one agent
구별되는 id는 두 capability를 분리하지만 도구 이름을 바꾸지는 않아요. StackOne의 서버는 컨텍스트와 액션에 따라 도구 이름을 짓기 때문에(bamboohr_list_employees), 같은 프로바이더의 두 계정은 같은 이름을 나열하고 실행이 id가 아니라 도구 이름에서 실패해요:
UserError: StackOneToolset 'stackone-crm-account' defines a tool whose name conflicts with
existing tool from StackOneToolset: 'bamboohr_list_employees'
PrefixTools로 네임스페이스를 지정하세요. 그것이 바로 그것을 위한 것이에요:
from pydantic_ai import Agent
from pydantic_ai.capabilities import PrefixTools
from pydantic_ai_harness import StackOne
agent = Agent(
'openai:gpt-5.6-sol',
capabilities=[
PrefixTools(StackOne(account_id='hr-account'), prefix='hr'),
PrefixTools(StackOne(account_id='crm-account'), prefix='crm'),
],
)
모델은 hr_bamboohr_list_employees와 crm_bamboohr_list_employees를 보고, 각각 자체 연결된 계정으로 라우팅돼요. 다른 프로바이더의 두 계정은 이미 다른 도구 이름을 나열하므로 접두사가 필요 없어요.
Bound large tool results
프로바이더 액션은 큰 export를 반환할 수 있어요. StackOne을 Tool Output Limits capability와 결합해 과대 도구 반환을 에이전트 전체에서 줄이세요:
from pydantic_ai import Agent
from pydantic_ai_harness import StackOne, ToolOutputLimits
agent = Agent(
'openai:gpt-5',
capabilities=[
StackOne(account_id='your-linked-account-id'),
ToolOutputLimits(),
],
)
Require approval
승인은 자동으로 활성화되지 않아요. 인간 확인이 필요한 작업에는 Pydantic AI의 도구 승인과 함께 공개 StackOneToolset을 사용하세요:
import os
from pydantic_ai import Agent
from pydantic_ai_harness.stackone import StackOneToolset
stackone_tools = StackOneToolset(
account_id=os.environ['STACKONE_ACCOUNT_ID'],
actions=['workday_create_worker'],
).approval_required()
agent = Agent('openai:gpt-5', toolsets=[stackone_tools])
결과 deferred 승인 요청은 연결된 가이드에 설명된 대로 처리하세요.
Define the agent in YAML or JSON
이 capability는 YAML 또는 JSON용 Pydantic AI agent spec 형식과도 함께 동작해요. API 키는 파일에 저장하지 말고 STACKONE_API_KEY에 두세요:
# agent.yaml
model: openai:gpt-5
capabilities:
- StackOne:
account_id: 'your-linked-account-id'
actions: ['*_list_*']
from pydantic_ai import Agent
from pydantic_ai_harness import StackOne
agent = Agent.from_file('agent.yaml', custom_capability_types=[StackOne])
spec 로더가 StackOne을 인스턴스화하는 방법을 알도록 custom_capability_types를 전달하세요.
Agent(toolsets=[...]) 또는 다른 툴셋 래퍼가 필요할 때 더 낮은 수준의 StackOneToolset을 직접 사용하세요.
커스텀 base_url과 URL 값 client는 HTTPS를 사용해야 해요. 툴셋은 auth 헤더를 추가하고 URL 값에 tool-mode 쿼리 파라미터가 없으면 추가해요. URL의 tool-mode가 구성된 모드와 충돌하면 다시 쓰기가 서명된 URL을 무효화하므로 오류를 발생시켜요. 서명된 URL로 search_execute를 사용할 때는 서명 전에 tool-mode=search_execute를 포함하세요. 사전 빌드된 클라이언트는 그대로 사용되며, HTTP(S) 전송, auth, 계정 선택, 도구 모드를 직접 구성하세요.
API reference
StackOne
Bases: AbstractCapability[AgentDepsT]
StackOne을 통한 사용자의 SaaS 계정(HRIS, ATS, CRM 등)의 액션.
인증, 도구 필터링, 사용 지침과 함께 StackOne의 MCP 엔드포인트를 통해 에이전트를 하나의 연결된 계정의 액션에 연결.
Attributes
account_id
작업할 연결된 계정(하나의 계정은 하나의 프로바이더 연결).
Type: str
id
안정적인 capability 및 툴셋 ID. account_id에서 파생되며 주어지지 않으면 그렇지 않아요.
하나의 계정은 하나의 프로바이더 연결이므로, 계정이 이 capability를 식별해요 — MCP 서버가 URL로 식별되는 것과 같아요. 'stackone'으로 고정하는 대신 파생하는 것이 한 에이전트가 두 개의 연결된 계정에 도달할 수 있게 해요. 그 id가 다르므로 두 capability로 남죠. 같은 계정 아래의 둘은 실수이며 충돌해요.
Type: str | None Default: None
description
capability가 요청 시 로드될 때 사용되는 라우팅 설명.
Type: str | None Default: _DEFAULT_DESCRIPTION
api_key
StackOne API 키. 기본값은 STACKONE_API_KEY 환경 변수.
Type: str | None Default: field(default=None, repr=False)
base_url
HTTPS StackOne API 호스트. 필요한 경우 리전 또는 스테이징 호스트를 가리키기.
Type: str Default: STACKONE_BASE_URL
actions
전체 도구 이름에 대한 fnmatch glob(대소문자 무시), 예: ['*_list_*']. actions를 주면 기본 tool_mode를 individual로 전환하며, 여기서 glob이 적용돼요.
Type: str | Sequence[str] Default: ()
tool_mode
individual은 활성화된 액션마다 도구 하나를 등록하고, search_execute는 두 개의 서버 측 메타 도구(카탈로그 검색, id로 액션 실행)를 등록하며 카탈로그가 아무리 커져도 프롬프트 면적이 일정해요. None은 search_execute를 선택하고, actions가 주어지면 individual을 선택해요.
Type: ToolMode | None Default: None
include_instructions
StackOne 사용 지침을 시스템 프롬프트에 주입.
Type: bool Default: True
metadata
모든 도구에 병합되는 메타데이터. CodeMode(tools={'code_mode': True})나 커스텀 prepare_tools 훅 같은 도구 선택 메커니즘에 사용 가능.
Type: Mapping[str, object] | None Default: None
client
기본 {base_url}/mcp 연결의 대체. URL 값은 HTTPS를 사용해야 해요. 사전 빌드된 클라이언트는 자체 전송, auth, 계정 선택을 유지하므로 account_id가 그들에 적용되지 않아요.
Type: MCPToolsetClient | None Default: field(default=None, repr=False)
Methods
get_toolset
def get_toolset() -> StackOneToolset[AgentDepsT]
StackOne 툴셋을 구축.
Returns
StackOneToolset[AgentDepsT]
get_instructions
def get_instructions() -> str | None
StackOne 사용 안내. 기본 MCP 툴셋은 자체적으로 제공하지 않아요.
Returns
from_spec
@classmethod
def from_spec(
cls,
account_id: str,
*,
id: str | None = None,
description: str | None = _DEFAULT_DESCRIPTION,
defer_loading: bool = False,
api_key: str | None = None,
base_url: str = STACKONE_BASE_URL,
actions: str | Sequence[str] = (),
tool_mode: ToolMode | None = None,
include_instructions: bool = True,
metadata: Mapping[str, object] | None = None,
) -> StackOne[AgentDepsT]
런타임 전용 client를 제외한 직렬화 가능한 옵션에서 구성.
Returns
StackOne[AgentDepsT]
get_serialization_name
@classmethod
def get_serialization_name(cls) -> str
agent-spec capability 이름을 반환.
Returns
StackOneToolset
Bases: MCPToolset[AgentDepsT]
에이전트 툴셋으로서 연결된 하나의 SaaS 계정의 StackOne 액션.
StackOne의 MCP 엔드포인트에 연결된 MCPToolset. URL 클라이언트는 StackOne auth와 계정 헤더를 받아요. 액션 필터링과 메타데이터 병합이 서버가 나열한 도구에 적용돼요. 사전 빌드된 클라이언트는 자체 전송 구성을 유지해요. 인스턴스는 전체 MCPToolset 표면을 지원해요.
사용 지침과 agent-spec 지원에는 StackOne capability를 사용하세요. approval_required() 같은 툴셋 조합자를 위해서는 이 클래스를 사용하세요.
Methods
init
def __init__(
*,
account_id: str,
api_key: str | None = None,
base_url: str = STACKONE_BASE_URL,
actions: Sequence[str] = (),
tool_mode: ToolMode | None = None,
metadata: Mapping[str, object] | None = None,
client: MCPToolsetClient | None = None,
id: str = 'stackone',
) -> None
StackOne MCP 툴셋을 구축.
Returns
Parameters
account_id : str
StackOne 요청에 사용되는 연결된 계정.
api_key : str | None Default: None
API 키, 또는 생략 시 STACKONE_API_KEY.
base_url : str Default: STACKONE_BASE_URL
HTTPS StackOne API 호스트.
actions : Sequence[str] Default: ()
개별 액션 도구 이름에 대한 대소문자 무시 glob. individual을 선택하며, 명시적 search_execute와 호환되지 않아요.
tool_mode : ToolMode | None Default: None
개별 도구 또는 검색/실행 쌍. 생략 시 추론.
metadata : Mapping[str, object] | None Default: None
각 도구 정의에 병합되는 메타데이터.
client : MCPToolsetClient | None Default: None
MCPToolset이 받아들이는 URL, FastMCP, 또는 사전 빌드된 클라이언트. 비URL 클라이언트는 자체 전송, auth, 계정 선택을 유지하므로 account_id가 그들에 적용되지 않아요.
id : str Default: 'stackone'
툴셋 ID. 여러 계정에는 구별되는 값을 사용하세요.