dsh-lark-bridge
English | 中文
A DeepSeek Harness plugin that bridges the DSH agent to the Feishu/Lark Open Platform. It provides a credential-resolved auth provider (tenant_access_token with auto-refresh), a suite of model-facing outbound tools (send message, read docx, read/write Bitable, call a Feishu bot/agent), and optional Phase 2 inbound: Feishu private-chat messages → in-process DSH agent → reply.
Why
The Feishu/Lark ecosystem has rich content (docs, bitables, agents) that an AI coding agent often needs to read and act on. This plugin turns those APIs into tools the model can call directly, instead of the user pasting content manually.
Installation
dsh plugin --profile web add github:<your-user>/dsh-lark-bridge
After install, add the bundle to your profile's dsh.profile.bundles (see Bundles).
Config
| Key | Default | Meaning |
|---|---|---|
appId |
omitted | Literal Feishu app id. Prefer appIdEnv so no secret enters config; a non-empty literal wins. |
appSecret |
omitted | Literal Feishu app secret. Prefer appSecretEnv. |
appIdEnv |
FEISHU_APP_ID |
Credential reference resolved per call through ctx.credentials, or from the process environment when that seam is absent. |
appSecretEnv |
FEISHU_APP_SECRET |
Credential reference resolved per call. |
baseURL |
https://open.feishu.cn/open-apis |
Feishu Open API base. Use https://open.larksuite.com/open-apis for Lark. |
timeoutMs |
30000 |
Cooperative tool-call budget per Feishu tool, enforced by dsh-tool-call-timeout-policy. |
enableSendMessage |
true |
Register the feishu_send_message tool. |
enableReadDoc |
true |
Register the feishu_read_doc tool. |
enableBitable |
true |
Register the bitable read/write tools. |
enableCallAgent |
false |
Register the feishu_call_agent tool (disabled by default — requires a configured bot/agent id). |
enableInbound |
false |
Start Feishu long-connection inbound (private chat → DSH agent → reply). |
inboundCwd |
process cwd | Working directory for inbound-created agent sessions. |
inboundAck |
true |
Send a short “received, working…” ack before the agent turn. |
- id: lark-bridge
name: dsh-lark-bridge
config:
appIdEnv: FEISHU_APP_ID
appSecretEnv: FEISHU_APP_SECRET
baseURL: https://open.feishu.cn/open-apis
appId and appSecret carry role('secret'), so they never ride a describe() response in any layer.
First-run onboarding
On first launch, the web UI shows a one-time dialog asking for the Feishu App ID / App Secret. Values are stored through the credentials domain (FEISHU_APP_ID / FEISHU_APP_SECRET references), never through settings, so secrets never ride a configuration response. You can dismiss it ("Configure later") and complete setup anytime by setting the environment variables before launch or entering the values through the credentials flow.
The acknowledgement persists in the ui-onboarding namespace, so the dialog shows once unless the onboarding copy version changes.
Tools
| Tool | Purpose |
|---|---|
feishu_send_message |
Send a text or card message to a user, chat, or by email. |
feishu_read_doc |
Fetch a docx document's content as plain text (via raw_content endpoint). |
feishu_list_doc_blocks |
Fetch a docx document's structured blocks, rendered with heading prefixes. Use when you need structure. |
feishu_list_bitable_tables |
List the tables in a Bitable app — use this first to discover table_id. |
feishu_bitable_list_records |
List records from a Bitable table (supports filter/sort). |
feishu_bitable_create_record |
Create a record in a Bitable table. |
feishu_bitable_update_record |
Update (overwrite) a record's fields in a Bitable table. |
feishu_bitable_batch_create_records |
Create multiple records in one call. |
feishu_call_agent |
Trigger a Feishu bot/agent by sending a message to its chat (indirect — Feishu has no direct server-side bot-run API). |
feishu_aily_start_skill |
Start an Aily (飞书智能伙伴) skill directly via server-side API. Requires enableAily=true. |
Each tool's timeout budget is config.timeoutMs, attached as ToolDefinition.timeoutMs.
Inbound (Phase 2 — private chat)
When enableInbound: true, the plugin opens a Feishu long connection (im.message.receive_v1) and handles private chats only (chat_type === p2p). Group chat is ignored for now.
Feishu p2p message
→ WS long connection
→ ctx.agents create/resume (session-feishu-<chat_id>)
→ agent.followup + whenIdle
→ reply via IM API
Feishu app setup
- Same App ID / Secret as outbound (one app is enough).
- Permissions: at least
im:message,im:message:send_as_bot,im:message.p2p_msg. - Event subscription: 长连接接收事件 +
im.message.receive_v1. - Start
dsh web(with this plugin) first, then save the long-connection setting in the open platform. - Do not run
feishu-dsh-bridge(or another WS client) for the same app at the same time — only one long connection wins.
Notes
- Replies wait for the full agent turn (no streaming yet).
- Unattended tool approvals may stall; use a permissive permission preset for Feishu-driven sessions if needed.
- Enable in
cordis.patch.ymlwithenableInbound: true(this repo’s patch already turns it on).
Bundles
TODO: declare dsh.bundle once the bundle contract is confirmed. Until then this plugin is installed as a plain dependency; see Known Limitations.
Model Experience
What the model sees
Each enabled tool appears with a JSON-schema-described parameter set and a one-line system-prompt section. The auth provider is invisible to the model — tokens are resolved per call from config/env, never passed through model-facing arguments.
Token effect
Outbound Feishu API calls cost no conversation tokens directly. Results returned to the model scale with Feishu's response size; feishu_read_doc truncates long documents.
KV Cache effect
Append-only; newly visible tool results follow the reusable request prefix and do not invalidate existing KV-cache entries.
Known Limitations
- Group inbound not yet — Phase 2 inbound handles private chat only; group
@comes later. - No streaming inbound replies — the bot waits for the full agent turn, then sends text.
- No
dsh.bundleauto-activation caveat may still appear depending on install path — see install notes; this package does declaredsh.bundleviapackage.json+cordis.patch.yml. - Agent invocation outbound is indirect — Feishu's server-side API for "call an agent" is limited;
feishu_call_agenttriggers a bot by mention rather than a direct server-side agent run. - One long connection per app — multiple WS clients for the same Feishu app will fight; keep inbound in this plugin only.
License
MIT
No comments yet. Be the first to write one.