Skip to main content
Glama
borgels

mcp-server-productive

by borgels

mcp-server-productive

Productive.io API v2용 MCP 서버 — 한 조직의 프로젝트, 작업, 시간 추적, 리소스 계획, 재무, CRM 및 보고서를 다룹니다.

Productive는 132개 리소스에 걸쳐 약 650개의 작업을 제공합니다. 이를 650개의 MCP 도구로 바꾸면 어떤 클라이언트의 도구 목록도 압도하게 되므로, 이 서버는 생성된 레지스트리로 구동되는 열두 개의 도구로 구성됩니다. 도구는 범용적이며, 레지스트리가 각 리소스가 실제로 무엇을 받아들이는지 알고 있습니다.

도구

탐색productive_search_capabilities, productive_describe_resource, productive_check_connection, productive_describe_custom_fields

읽기productive_list (필터, 정렬, include, 페이지네이션, 그룹화가 포함된 26개 보고서 엔드포인트), productive_get

쓰기productive_create, productive_update, productive_delete, productive_run_action (보관, 복원, 승인, 마감, 복사, 확정, 전송 등 150개의 명명된 동사), productive_track_time, productive_commit_operation

사용자별 인증(선택)productive_connect, productive_status, productive_disconnect인증 참조

productive_search_capabilities부터 시작하세요. Productive의 리소스 이름은 고유합니다. 예산은 deal이고, 보드 열은 workflow_status이며, 타임시트 승인은 time_entries에 있습니다. 추측은 호출 비용을 초래합니다.

Related MCP server: productive-mcp-rb2

레지스트리

src/productive/registry.generated.tsscripts/generate-registry.mjs가 Productive의 공개 OpenAPI 문서에서 생성한 것이며 커밋되어 있으므로, CI는 네트워크가 필요 없고 스펙 변경은 검토 가능한 diff로 나타납니다. 레지스트리는 모든 리소스에 대해 필터 필드, 정렬 키, 보고서 그룹 키, include 가능한 관계, 생성 및 업데이트 시 필수로 표시된 쓰기 가능 속성, 그리고 각 명명된 작업을 기록합니다.

그 덕분에 열두 개의 도구가 정직함을 유지할 수 있습니다. productive_describe_resource는 한 리소스에 대한 정확한 계약을 돌려주며, 모든 인자는 요청이 나가기 전에 그 계약과 대조 검사됩니다.

npm run registry:generate로 재생성합니다(로컬 스펙 사본을 사용하려면 경로 인자를 추가하세요). 수작업으로 작성된 분류 — 위험 등급, 외부 노출 플래그, 차단된 작업 — 가 스펙의 어떤 경로와도 더 이상 일치하지 않으면 생성기는 빌드를 실패시키므로, 업스트림의 이름 변경이 조용히 가드를 제거할 수 없습니다.

측정된 API 동작

여기의 모든 내용은 실제 조직에서 검증되었습니다. 스펙과 API가 중요한 부분에서 서로 다르기 때문입니다.

시간은 분 단위, 금액은 최소 화폐 단위입니다. 시간 항목 2는 2분입니다. 응답도 동일한 단위로 돌아옵니다.

알 수 없는 필터, 정렬, include는 크게 실패합니다. unsupported_filter, sort_param_unsupported, unsupported_include와 함께 HTTP 400이 반환됩니다. 따라서 여기서 검증하는 것은 안전망이 아니라 더 나은 오류입니다.

알 수 없는 쓰기 속성은 조용히 실패합니다. 오타가 있는 속성으로 PATCH를 보내면 HTTP 200이 반환되고 아무것도 변경되지 않습니다 — 성공과 구별할 수 없습니다. 따라서 이 서버는 리소스가 선언하지 않은 속성을 거부하며, 발생하지 않은 쓰기를 보고하지 않습니다. 이것이 레지스트리가 하는 가장 유용한 일입니다.

모든 필드에는 정확히 여섯 개의 필터 연산자가 있습니다: contains, eq, gt, lt, not_contain, not_eq. 스펙은 필드당 네 개만 나열하고 실제로 동작하는 gt/lt를 빠뜨립니다. gte, lte, in, not_in, starts_with, ends_with, blank, present는 모두 unsupported_filter_operation으로 거부됩니다. 포함 비교는 없으므로, 포함 범위가 필요하면 리소스 자체의 after/before 또는 <field>_after/<field>_before 필터 필드를 사용해야 합니다.

page[size]는 200에서 상한이 정해지며 조용히 잘립니다. 500을 요청하면 오류 없이 200이 반환됩니다. 결과에는 totalnextPage가 포함되어 한 페이지가 전체 답으로 오인되지 않습니다.

PATCH는 진정한 부분 업데이트입니다. 생략된 속성은 값을 유지하므로 전체 레코드를 다시 보낼 필요가 없습니다.

data.type은 검사되지 않습니다. type: "projects"로 작업을 패치하면 성공하고 변경이 적용됩니다. 이 서버는 그래도 올바른 타입을 보냅니다.

조직 ID가 "제공되어야 한다"는 403은 누락이 아니라 잘못되었음을 의미할 수 있습니다. 동일한 no_organization_id 코드가 누락된 헤더와 토큰이 도달할 수 없는 조직을 모두 포함합니다.

누락된 기능은 403이 아니라 404로 응답합니다. /boards는 해당 기능이 없는 조직에서 404를 반환하며, 이는 경로가 깨진 것처럼 보입니다.

삭제는 복원 가능할 수 있습니다. 삭제된 작업은 item_typeitem_id와 함께 deleted_items에 나타나며 해당 리소스의 restore 작업을 통해 복원할 수 있습니다. 작업에 대해서만 검증되었으므로 모든 유형에 적용된다고 가정하지 마세요.

GET /users는 유일한 호출자 범위 엔드포인트입니다. 정확히 하나의 레코드 — 바로 사용자 — 를 반환하며, 이 서버가 토큰 소유자를 식별하는 방법입니다. /users/me는 존재하지 않으며 해당 경로는 404를 반환합니다. /organization_memberships에 주의하세요. 이는 고정된 조직으로 범위가 한정되지 않고 호출자가 속한 모든 조직에 걸친 멤버십을 나열하므로, 행 수가 인원수가 아닙니다.

속도 제한 헤더가 없습니다. x-request-id만 있으며, 이 서버의 오류가 이를 인용합니다. 한도를 탐색하지 말고 429에서 백오프하세요.

권한

기본적으로 모두 꺼져 있는 네 개의 스위치. 읽기 전용 서버가 유용하고 안전한 기본값입니다.

스위치

적용 범위

PRODUCTIVE_ENABLE_WRITES

마스터 스위치. 이 스위치 없이는 아무것도 변경되지 않습니다.

PRODUCTIVE_ENABLE_FINANCIALS

금전, 가격, 급여, 고객이 받는 문서: 인보이스, 라인 항목, 결제, 청구서, 비용, 구매 주문, 제안서, 계약서, 가격, 요금 카드, 급여, 간접비, 세율, 은행 계좌, 자회사.

PRODUCTIVE_ENABLE_ADMIN

접근 및 조직 전체 구성: 인력, 멤버십, 권한 집합, 팀, 초대, 사용자 정의 필드, 웹훅, 통합, 승인 및 시간 추적 정책.

PRODUCTIVE_ENABLE_DELETES

계층 게이트에 더해 삭제.

Productive에는 마스터 스위치 하나로는 충분하지 않습니다. 동일한 API가 작업을 이동하고, 인보이스를 발행하고, 권한 집합을 부여하는데, 이는 서로 다른 세 가지 결정입니다. 프로젝트 작업을 실행하도록 신뢰받은 서버가 그로 인해 인보이스를 보낼 수 있어서는 안 됩니다.

PRODUCTIVE_ALLOWED_RESOURCES / PRODUCTIVE_DENIED_RESOURCES는 인스턴스를 더 좁히며 읽기에도 적용됩니다. 시간 추적에만 범위가 한정된 인스턴스는 급여도 읽을 수 없어야 합니다.

스위치와 관계없이 절대 노출되지 않는 것: passwords, sessions, organization_subscriptions, 인증이 없는 public/* 공유 링크, 그리고 PATCH /users/{id}/update_password. 이들은 게이트로 차단되는 대신 레지스트리에서 아예 빠져 있으므로, 어떤 정책 버그도 이를 다시 열 수 없습니다.

2단계 쓰기

일반적인 프로젝트 작업 — 작업, 시간 항목, 예약, 댓글 — 은 한 번의 호출로 작성됩니다. 모든 시간 항목에 핸드셰이크를 요구하면 사람들이 가장 많이 하는 일에 서버를 사용할 수 없게 됩니다.

폭발 반경이 더 넓은 모든 것은 스테이징됩니다. 도구는 정확한 요청과 해시를 반환하고 아무것도 보내지 않으며, productive_commit_operation은 작업이 변경되지 않은 채로 돌아올 때만 실행합니다. 여기에는 재무 및 관리 계층, 모든 삭제, 조직을 떠나는 모든 것, 그리고 모든 bulk_* 작업이 포함됩니다. 이 작업들은 필터가 일치하는 모든 레코드에 적용되므로 명시적 필터 없이는 실행을 거부합니다.

여섯 개의 작업은 실행되는 순간 조직 외부의 누군가에게 도달하기 때문에 outward로 표시됩니다: invoices.send, invoices.send_einvoice, people.invite, people.resend, organizations.resend_code, 그리고 invitation 생성.

인증

두 가지 모드. PRODUCTIVE_ORGANIZATION_ID는 두 모드 모두에서 필수이며 도구 인자로 사용되지 않습니다.

사용자별 토큰(권장)

각 개인은 자신의 Productive 토큰을 연결하므로, Productive가 그들의 권한을 적용하고 그들이 한 일에 이름을 기록합니다.

이것은 대부분의 시스템보다 Productive에서 더 중요합니다. Productive는 작업을 사람에게 귀속시킵니다. 시간 항목은 person_id에 속하며, 모든 변경은 활동 로그에 토큰 소유자로 기록됩니다. 이 로그는 고객 인보이스를 방어하는 근거가 됩니다. 하나의 공유 토큰을 사용하면 그 로그는 서비스 계정이 모든 것을 했다고 표시됩니다.

PRODUCTIVE_PER_USER_AUTH=true
PRODUCTIVE_TRUST_FORWARDED_USER=true
PRODUCTIVE_ENCRYPTION_KEY=<min 16 chars>
PRODUCTIVE_STORE_PATH=/data/store.json
PRODUCTIVE_PUBLIC_BASE_URL=https://productive.example.com
# PRODUCTIVE_API_TOKEN deliberately unset

절차:

  1. 호출자가 productive_connect를 실행하면 10분간 유효한 일회용 링크를 받으며, 이는 호출자의 신원에 바인딩됩니다.

  2. 링크를 열고 Productive의 설정 → API 통합에서 만든 토큰을 붙여넣습니다. 토큰은 브라우저에서 서버로 직접 전달되므로 대화 기록에 들어가지 않습니다. Productive 토큰은 전체 계정과 동등한 bearer 자격이며, 아래에서 측정한 대로 일반적으로 둘 이상의 조직에 도달합니다.

  3. 저장하기 전에 서버는 해당 토큰과 이 조직의 ID로 GET /users를 호출합니다. 한 번의 호출로 세 가지를 증명합니다: 토큰이 유효하고, 조직에 도달할 수 있으며, 누구의 것인지. 그런 다음 페이지에서 어떤 계정이 연결되었는지 확인합니다.

  4. 토큰은 AES-256-GCM으로 저장 시 암호화되며, 검증된 신원당 한 행씩 저장됩니다.

주의할 점:

  • 신원은 게이트웨이에서만 얻습니다. X-MCP-UserPRODUCTIVE_TRUST_FORWARDED_USER=true일 때만 읽히며, MCP 클라이언트가 제어하는 어떤 것에서도 읽히지 않습니다. 검증된 토큰에서 헤더를 설정하고 클라이언트가 제공한 사본을 제거하는 게이트웨이 뒤에서만 활성화하세요. 그렇지 않으면 호출자가 아무 신원이나 지정하고 그 사람으로 행동할 수 있습니다.

  • 폴백이 없습니다. 등록되지 않은 호출자는 PRODUCTIVE_API_TOKEN이 설정되어 있어도 공유 토큰이 아닌 NOT_CONNECTED를 받습니다. 폴백은 빌린 권한을 넘겨주는 것이며, 이 모드가 제거하려는 바로 그 실패입니다.

  • /productive/enroll은 사용자의 브라우저가 접근할 수 있어야 하며, MCP 게이트웨이를 우회해야 합니다. 브라우저는 게이트웨이의 bearer 토큰을 전달할 수 없습니다. PRODUCTIVE_PUBLIC_BASE_URL/productive/*를 컨테이너로 직접 라우팅하세요. 그 보안은 일회용이고 신원에 바인딩된 상태 토큰입니다.

  • PRODUCTIVE_STORE_PATH를 볼륨에 유지하고 PRODUCTIVE_ENCRYPTION_KEY를 안정적으로 유지하세요. 변경하면 저장된 모든 토큰을 복호화할 수 없게 됩니다.

  • 토큰 자체의 Productive 이메일이 호출자의 디렉터리 주소와 다른 경우, 페이지와 productive_status에서 크게 보고되고 그래도 연결됩니다. 대신 거부하려면 PRODUCTIVE_REQUIRE_EMAIL_MATCH=true를 설정하세요. 다른 사람의 토큰을 붙여넣는 사람은 이미 그 토큰을 보유하고 있으므로 거부해도 보안상 얻는 것이 거의 없고, 다른 주소의 Productive 계정은 충분히 있을 법한 일이기 때문에 기본값은 꺼져 있습니다.

  • 사용자별 인증은 권한과 귀속을 분리하지, 조직을 분리하지 않습니다. 조직 고정은 여전히 모든 사람에게 적용됩니다.

공유 토큰

PRODUCTIVE_API_TOKEN을 하나의 토큰으로 설정하세요. 간단하며 stdio나 단일 운영자에게 적합합니다. 하지만 모든 호출자가 그 토큰 소유자로 행동하며, 그들의 권한을 사용하고, Productive의 활동 로그는 모든 변경을 그 사람에게 귀속시킵니다.

PRODUCTIVE_TRUST_FORWARDED_USER는 여기서도 여전히 유용합니다: 사람 형태의 쓰기(시간 항목, 예약)는 토큰 소유자가 아니라 확인된 호출자로 기본 설정되며, 서버는 주소가 아무도 또는 두 명 이상의 사람과 일치할 때 추측하기를 거부합니다. productive_check_connection은 어느 쪽이든 토큰 소유자를 명명하므로 귀속이 놀라운 일이 되지 않습니다.

다중 조직

하나의 인스턴스는 정확히 하나의 조직만 서비스합니다. X-Organization-Id는 환경에서 가져오며 도구 인수가 아니므로, 어떤 코드 경로도 — 일반 도구를 포함해서 — 다른 테넌트에 도달할 수 없습니다. 두 번째 조직을 위해 두 번째 인스턴스를 실행하세요. 이미지는 동일합니다.

이것은 이론적인 이야기가 아닙니다. 단일 토큰이 여러 조직에 정기적으로 도달합니다. 이 서버를 개발할 때 사용한 계정에서 GET /organizations는 세 개를 반환했고, 헤더만 바꿔도 그 사이를 이동했습니다(나머지 두 개는 "찾을 수 없음"이 아닌 403 subscription_expired로 응답했습니다). 헤더가 경계의 전부이므로, 인수로 전달되는 대신 고정되는 것이며, 등록된 사용자별 토큰이 저장되기 전에 조직에 대해 검증되는 이유이기도 합니다.

구성

.env.example을 참조하세요. 필수 변수 두 개는 PRODUCTIVE_API_TOKEN(Productive의 Settings → API integrations; 생성 사용자의 권한을 상속함)과 PRODUCTIVE_ORGANIZATION_ID(Productive URL의 숫자 ID)입니다.

PRODUCTIVE_AUDIT_LOG를 설정하면 정책이 거부한 시도까지 포함하여 변경 시도마다 JSON 줄 하나를 추가합니다. 요청 본문은 의도적으로 기록하지 않습니다. 요청 본문에는 급여, 요율, 개인 데이터가 담겨 있으며, 원본 시스템만큼 엄격히 보호해야 하는 감사 추적은 좀처럼 읽히지 않기 때문입니다.

실행

npm install
npm run dev          # stdio
npm run dev:http     # streamable HTTP on :3000/mcp (stateless), /healthz open
npm test
npm run smoke:live   # reads a real organization; stages one write, commits nothing

Docker 이미지: ghcr.io/borgels/mcp-server-productive(main에 푸시할 때 게시됨).

라이선스

Apache-2.0.

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • ClickUp MCP — wraps the ClickUp REST API v2 (BYO API key)

  • Product Hunt MCP — wraps the Product Hunt GraphQL API v2 (api.producthunt.com)

  • Direct access to your Sanity projects (content, datasets, releases, schemas) and agent rules

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/borgels/mcp-server-productive'

If you have feedback or need assistance with the MCP directory API, please join our Discord server