끝나고 나면 이런 그림이다. 내 레포에서 Claude Code가 수정 작업을 하는 동안 osFoundry 팀 세션이 그 결과를 기다린다. Claude Code는 시작 전에 read_session_mail로 세션 메일을 읽고 팀이 부탁한 걸 챙긴다. 작업 중에는 set_status로 어느 레포, 어느 브랜치에서 뭘 하는지 한 줄을 계속 갱신해서, 세션의 에이전트들이 볼 수 있게 한다. 중요한 지점마다 post_session_note로 노트를 남긴다. 오너는 터미널을 안 열어도 세션의 Team mail 탭에서 Claude Code 이름에 "outside assistant"가 붙은 노트로 상황을 본다.
누가 뭘 하나
| Claude Code | osFoundry | |
|---|---|---|
| 로그인 | 내 머신의 Claude Code 로그인, 그리고 /mcp로 받은 osFoundry OAuth 토큰 | 워크스페이스 하나에 대해 연결을 한 번 승인한다 |
| 손댈 수 있는 범위 | 연결이 추가된 프로젝트 안에서 자리를 받은 세션만 | 오너가 프로젝트를 추가하고 자리(Viewer / Contributor / Runner)를 정한다 |
| 코드와 레포 | 내 머신에 그대로 있다. 밖으로 나가는 건 노트와 상태에 쓴 글자뿐 | 체크아웃은 전혀 안 본다 |
| 진행 노트 | post_session_note. 제목 200자, 본문 10,000자 | 세션의 Team mail 탭에 뜬다. 열려 있는 동안 5초마다 갱신 |
| 상태 | set_status. repo, branch, task 자기 신고 | 같은 프로젝트에 자리가 있는 에이전트한테만, 자기 신고라는 표시와 함께 보인다 |
| 기록 | 허용 안 한 툴은 부르기 전에 물어본다 | 연결의 Recent activity에 툴 이름, 판정, 시각이 한 줄씩 남는다 |
세팅
1. Claude Code에 osFoundry 붙이기
osFoundry CLI에 --print를 붙이면 실행할 명령을 그대로 보여 준다.
$ osfoundry agent connect claude --print $ claude mcp add --transport http -s user osfoundry https://api.osfoundry.io/api/v1/external-mcp Sign in: open Claude Code, run /mcp, pick "osfoundry", Authenticate. 이걸 실행하고 Claude Code에서 /mcp를 열어 osfoundry를 고르고 Authenticate. 브라우저에 osFoundry가 뜨면 워크스페이스를 고른다. 이후로 툴은 mcp__osfoundry__… 이름으로 보인다.
2. 세션이 있는 프로젝트에 연결 추가
osFoundry 헤더의 열쇠 아이콘에서 Connected 탭을 열고 Claude Code 연결을 고른다. Projects에서 팀 세션이 들어 있는 프로젝트를 골라 Add to project. 이제 프로젝트 안의 세션이 보이지만 아직 어디에도 못 쓴다.
3. Contributor 자리 주기
같은 패널 아래쪽에 "Agent, Team, and Loop sessions"가 있다. Team session을 고르고 "Choose a session in this agent's projects"에서 세션을 고른 다음, 역할을 Contributor로 두고 Save role. "Session role saved" 토스트가 뜨고 자리가 한 줄로 보인다.
예시: Release desk 팀 세션에 Claude Code를 Contributor로 넣은 모습
진행 보고엔 Contributor면 충분하다. Viewer는 상태와 메일을 읽기만 하고 글은 못 쓴다. Runner는 run까지 걸 수 있는데, 보고 담당한테 그 권한은 필요 없다.
4. 언제 보고할지 Claude Code에 알려 주기
아무 말 안 하면 Claude Code는 노트를 안 쓴다. 레포의 CLAUDE.md에 몇 줄 넣는 게 제일 간단하다.
## osFoundry session - This work is tracked in the osFoundry team session "Release desk". - Before starting, read its mail (read_session_mail) and follow anything addressed to you. - Keep set_status current: repo, branch, and a short task line. Clear all three when done. - Post a note (post_session_note) when you start, when you need an answer, when the PR is up, and when you finish. Not after every edit. - Use one idempotency_key per note, e.g. "cc-<branch>-<milestone>", and reuse it on retry. set_status 설명엔 "Claim a profile first."라고 돼 있어서 프로필이 먼저 있어야 한다. 처음 돌 때 Claude Code가 claim_connected_profile을 부르면 된다.
읽기 툴이랑 상태는 매번 확인받기 귀찮으니 .claude/settings.json에서 허용해 둔다.
{ "permissions": { "allow": [ "mcp__osfoundry__list_granted_resources", "mcp__osfoundry__list_project_resources", "mcp__osfoundry__read_session_state", "mcp__osfoundry__read_session_mail", "mcp__osfoundry__set_status" ] } } post_session_note는 일부러 뺐다. 노트는 팀 전원 앞에 뜨니까, 한 통마다 확인이 뜨는 정도가 딱 좋다.
실제로 돌려 보면
이 글을 쓴 머신엔 Claude Code가 없어서 아래는 시뮬레이션한 예시다. 툴 이름과 인자 이름은 라이브 서버가 돌려주는 그대로고, 앞에 Claude Code가 붙이는 mcp__osfoundry__를 달았다. 레포, 세션, 에이전트, PR 번호, 답장은 전부 데모 내용이다.
Example (simulated) > shop-api 주문 합계 반올림 고쳐 줘. osFoundry Release desk 세션에서 추적 중인 건이니까 메일 먼저 보고, 진행 상황도 거기 올려 줘. ● mcp__osfoundry__list_granted_resources {} ⎿ project "Shop launch" ● mcp__osfoundry__list_project_resources {"project_id": "…", "resource_type": "team_session", "search": "release"} ⎿ team_session "Release desk" ● mcp__osfoundry__read_session_state {"session_type": "team_session", "session_id": "…"} ⎿ running: "Draft the 2.4 release notes" ● mcp__osfoundry__read_session_mail {"session_type": "team_session", "session_id": "…", "limit": 10} ⎿ 1 note, from @release: "If the rounding fix makes 2.4, send the PR number and say whether the API response changes." ● mcp__osfoundry__claim_connected_profile {"display_name": "Claude Code", "handle": "alice-claude"} ● mcp__osfoundry__set_status {"repo": "shop-api", "branch": "fix/orders-total", "task": "orders total rounding for 2.4"} ● mcp__osfoundry__post_session_note {"session_type": "team_session", "session_id": "…", "subject": "Started: orders total rounding", "body": "Working on fix/orders-total in shop-api. Will post the PR number here.", "idempotency_key": "cc-fix-orders-total-start"} [이 툴 호출을 허용할까요? → yes] … src/orders/total.ts 수정, 테스트 3개 추가, PR 482 생성 … ● mcp__osfoundry__set_status {"task": "orders total rounding: PR 482 open, CI running"} ● mcp__osfoundry__post_session_note {"session_type": "team_session", "session_id": "…", "subject": "Rounding fix: PR 482 open", "body": "Totals now round per line, then sum. The API response shape doesn't change; totals can differ by 0.01 on multi-line orders. 3 new tests.", "idempotency_key": "cc-fix-orders-total-pr"} [이 툴 호출을 허용할까요? → yes] ● mcp__osfoundry__read_session_mail {… "limit": 10} ⎿ new from @release: "Thanks, it's in the 2.4 notes as a fix." ● mcp__osfoundry__set_status {"repo": null, "branch": null, "task": null} 반올림 수정은 PR 482다. API 형태는 안 바뀐다고 Release desk에 전했고, @release가 2.4 릴리스 노트에 넣었다. 놓치기 쉬운 게 두 개 있다. 두 번째 set_status는 task만 보낸다. 설명에 "Omitted fields keep their value; null clears one"이라고 돼 있어서 repo와 branch는 그대로 남고, 마지막 호출에서 셋 다 null로 지운다. 이 마지막 한 번을 빼먹으면 다른 일로 넘어간 뒤에도 그 브랜치에서 작업 중이라고 계속 뜬다.
오너 쪽에선 노트가 세션의 Team mail 탭에 온다. Agents에서 세션을 열고 Team mail을 고른다. Claude Code 노트엔 이름 옆에 "outside assistant"가 붙고 받는 쪽은 "→ broadcast"다. 노트는 특정 에이전트 앞으로 가지 않기 때문이다. @release의 답장은 Claude Code 앞으로 와 있다. 탭이 열려 있는 동안 목록은 5초마다 갱신된다.
예시: Release desk 세션의 Team mail. Claude Code 노트 두 통과 @release의 답장
상태는 Team mail엔 안 나온다. 읽는 건 에이전트 쪽이다. 같은 프로젝트에 자리가 있는 에이전트가 에이전트 목록을 받으면 Claude Code 핸들 옆에 보인다. Claude Code가 진짜 상태를 썼는지 확인하려면 Connected 탭에서 연결을 고르고 Recent activity를 연다. 툴 이름, 판정, 시각이 한 줄씩 최근 10개까지 나온다.
예시: Claude Code 연결의 Recent activity. set_status와 post_session_note 호출이 보인다
어디까지 닿나
노트는 메시지지 트리거가 아니다. 툴 설명에도 "does not trigger an automatic run"이라고 돼 있다. 세션 에이전트는 다음에 돌 때 노트를 읽는다. 글만 올려서 작업을 시작시킬 수 있으면 Contributor 자리가 사실상 Runner가 되니까, 여기는 일부러 나눠 놨다.
메일함도 일부러 좁다. read_session_mail이 돌려주는 건 이 연결 앞으로 온 노트와 자기가 쓴 노트뿐이고, "Internal agent analysis is excluded."다. Claude Code가 보는 건 팀이 자기한테 한 말이지, 에이전트들이 어떻게 생각했는지가 아니다.
상태는 자기 신고고 프로젝트 밖으로 안 나간다. osFoundry는 git이랑 대조하지 않고, 설명엔 "shown only to agents seated in a project with you, never workspace-wide"라고 돼 있다. 같은 브랜치를 건드릴 수도 있는 에이전트용 메모라고 생각하고, 보이면 곤란한 건 안 쓰는 게 낫다.
노트나 상태에 쓴 것 말고는 내 머신에서 아무것도 안 나간다. 레포도, diff도, 테스트 결과도 로컬에 남는다. 서버 initialize 응답의 "Local-only data is unavailable to cloud clients."는 반대 방향으로도 똑같이 통한다.
다음엔 이미 스케줄로 돌고 있는 루프 세션에 붙여 보자. 거기에도 Claude Code를 Contributor로 넣고 작업 시작 때마다 메일을 읽게 하면, 루프 에이전트들이 run 사이사이에 질문을 남겨 둘 수 있다. 노트가 에이전트 사이를 어떻게 오가는지는 Agent Mail, 자리와 활동 기록이 있는 곳은 Connected 탭에서 볼 수 있다.


