DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

dsh-a2a-server

A2a Server

面向 DeepSeek Harness 的入站 A2A(Agent2Agent)协议服务器:发布 Agent Card,并让任何兼容 A2A 的对等方将任务提交给 harness agent

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add dsh-a2a-server@0.4.0
README兼容性版本

兼容性与来源证明

A2a Server 以 dsh-a2a-server 发布,当前版本为 0.4.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
any
发布来源
npm
Registry 更新时间
2026/11/4

版本

0.4.0stable
2026/11/4
0.3.0stable
2026/10/22
0.2.0stable
2026/9/4
查看其余 2 个版本收起版本
0.1.0stable
2026/8/22
0.1.1stable
2026/8/17

相关插件

正在加载相关插件…

最新版
0.4.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
1 MB
文件数
124
Surface
any
许可证
MIT
发布源
npm
GitHub
★ 2
周下载
257
安全扫描
✓ v0.4.0 扫描通过
最近提交
2026/11/4
查看源码 ↗项目主页 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 agents-orchestration 分类下经过校验的插件。

Hindsight Coding Agents@vectorize-io/hindsight-coding-agents面向编程代理的仅反思式 Hindsight 长期记忆(可插拔支持多种运行框架:opencode、……),自动在后台导入(无需设置 CLI)。Liangshen@linxin666/dsh-liangshen适用于 dsh Web GUI 的 LiangShen (梁神) agent preset 及其 composer lever。主机部分在激活时将内置 preset 声明到 harness 的 agent-preset 注册表中(declare = enabled),因此无需写入任何内容,preset 即可供新会话选择Remote Bridge@linxin666/dsh-remote-bridgeDSH 远程桥接:主机端通过唯一且精确的 /ios/v1 WebSocket 路由提供协议 v1——会话列表、历史记录基线、提示、包含工具活动的实时回合增量、中断以及进程内代理审批——连接到通过一次性配对的设备Ds Botds-botDS Bot:DeepSeek Harness 的一组长期运行的 Bot,支持主 Bot、Bot 间消息和群聊

README

dsh-a2a-server

Inbound A2A protocol server for DeepSeek Harness.
Publish an Agent Card, accept tasks from any compliant peer.
Everything is a plugin — this is one.

English · 简体中文

A community plugin, not an official DeepSeek product.

dsh-a2a-server makes a DeepSeek Harness agent reachable over the A2A (Agent2Agent) protocol. It serves an Agent Card at a well-known URI and implements the v1.0 JSON-RPC binding, so any compliant peer that knows the deployment's URL can discover the agent and submit tasks to it.

The plugin is inbound only: it never connects to another agent. There is no client, no peer directory, and no A2A subagent provider. It is a transport adapter over ctx.agents, not a capability seam.

For a local configuration UI and cross-network access, use the companion Talk2MyAgent setup guide. See the deployment and migration guide for visitor permissions, automatic briefings, private owner access and Tailscale.

Install

dsh plugin --profile web add dsh-a2a-server@0.4.0

dsh plugin forwards to pnpm inside the profile directory and appends this bundle to dsh.profile.bundles, because the package declares dsh.bundle. Since DSH v0.2.1-alpha.1, --profile must come before any pnpm arguments — the forms above already do.

To work from a checkout instead, point it at the directory:

dsh plugin --profile web add ./path/to/dsh-a2a-server
RequirementSupplied by
ctx.agentsdsh-base
ctx.credentialsdsh-base
ctx.webServerdsh-web-app
ctx.tools and ctx.systemPromptrequired visitor tool and prompt isolation services
ctx.sessionProjections (optional)composition; exposes task lifecycle projections

The plugin stays PENDING until all required services exist. ctx.webServer ships in dsh-web-app rather than dsh-base, so a headless profile needs @deepseek-ai/dsh-host-webserver mounted before this bundle serves anything. dsh --profile <name> --dump-config prints the composed rows.

Upgrading to 0.4.0

Version 0.4.0 requires DSH >=0.2.1-rc.2 <0.3.0. Stop the agent, install dsh-a2a-server@0.4.0 into its existing profile, then restart it. Owner RPC and monitoring now use authenticated local IPC; update the companion Portal as well. Visitors retain chat and scoped workspace reads, while other tools are denied. An empty trustedPeers: [] denies all visitors. Task results persist across restart within the configured retention window.

The current Talk2MyAgent Portal configures default-on hourly briefings with one persistent switch. The plugin alone does not enable automatic briefing without its briefing configuration. Portal automatically prepares Microsandbox for per-visitor isolation. Public data is copied read-only, excluding node_modules; private files persist on independent visitor disks. Idle VMs pause after 30 seconds and stop after 10 minutes. Existing standalone configurations keep their selected execution mode; installing the plugin alone does not enable a VM. See the sandbox guide and 0.4.0 release notes.

Quick start

The bundled example composition runs a real model and a listening server.

pnpm install
A2A_PEERS="alice:demo123" A2A_PORT=9922 pnpm serve
$env:A2A_PEERS = "alice:demo123"
$env:A2A_PORT = "9922"
pnpm serve

Peer names are arbitrary — alice is this demo's default, not a protocol fixture. Name as many as you like, and either carry the token inline or store it under the derived credential reference:

A2A_PEERS="ops:tok1,research:tok2"   # inline
A2A_PEERS="ops,research"             # tokens from A2A_PEER_OPS / A2A_PEER_RESEARCH

The model credential is resolved through ctx.credentials, so an existing DEEPSEEK_API_KEY in the harness home, either .env layer, or the process environment is picked up unchanged. A missing credential fails the boot.

Fetch the card and submit a task:

curl -s http://127.0.0.1:9922/.well-known/agent-card.json

curl -s http://127.0.0.1:9922/a2a \
  -H "authorization: Bearer demo123" \
  -H 'content-type: application/json' \
  -H 'a2a-version: 1.0'   -d '{"jsonrpc":"2.0","id":1,"method":"SendMessage","params":{
        "message":{"messageId":"m1","role":"ROLE_USER",
                   "parts":[{"text":"hello"}]}}}'
VariableDefaultMeaning
A2A_PEERSalicename[:token] list; a token is required for each
A2A_PORT9900Listening port
A2A_SEND_MODEblockblock or immediate
A2A_WORKSPACE_ROOTtemp dirShared public data; visitor workspaces live outside this root
DEEPSEEK_MODELdeepseek-v4-flashModel id requested from the adapter

A one-shot probe runs 67 checks against a live server and exits non-zero on any mismatch:

pnpm probe                                        # defaults to :9922 / demo123
node example/probe.mjs http://127.0.0.1:9922 demo123

Interface

RouteMethodAuth
/.well-known/agent-card.jsonGETPublic by default
/.well-known/agent.jsonGETPublic by default
{basePath} (default /a2a)POSTBearer required
{basePath}/admin/contexts[/<id>]GETLocal IPC only + admin token; never registered on public HTTP
{basePath}/admin/prepare-stopPOSTLocal IPC + admin token; drain tasks and stop sandboxes before terminating DSH
JSON-RPC methodStatus
SendMessageWaiting negotiated per request
SendStreamingMessageSSE
GetTaskIdempotent; answers after settlement
ListTasksCursor-paginated, filterable, live and retained tasks
CancelTaskCancels the running turn
SubscribeToTaskLive stream; -32004 on a terminal task
GetExtendedAgentCardExtra skills for an authenticated peer; -32007 when unconfigured
*TaskPushNotificationConfig-32003

Only A2A v1.0 is served. The v0.3 method names, kind discriminators, lowercase enums, and nested file parts are gone rather than aliased: every reply this server writes is v1.0 JSON, which a v0.3 client could not read, so answering a v0.3 request would fail further from its cause than refusing it. A retired method answers -32601 naming its replacement, and an explicit A2A-Version: 0.3 answers -32009 (VersionNotSupportedError). A request with no A2A-Version header is served as 1.0 — the only version this interface declares on its card.

What that means concretely, against v0.3:

Concernv0.3v1.0 as served here
Task referenceparams.taskIdparams.id
SendMessage resultbare Task{ "task": … }
Task state"working""TASK_STATE_WORKING"
Message role"user""ROLE_USER"
Part{"kind":"text","text":…}{"text":…}; file parts flatten to url/raw/filename/mediaType
Stream frame{"kind":"status-update",…,"final":true}{"statusUpdate":{…}}; the stream's close is the terminal signal
Stream openinga non-final status updatethe Task object itself
Wait controlconfiguration.blockingconfiguration.returnImmediately (inverted; blocking is the default)
Card endpointurl + preferredTransportsupportedInterfaces[], each carrying its own protocolVersion
Card authsecuritySchemes + securityschemes wrapped in httpAuthSecurityScheme; securityRequirements
Extended cardsupportsAuthenticatedExtendedCardcapabilities.extendedAgentCard
A2A error detailnoneerror.data[] carrying a google.rpc.ErrorInfo with reason and domain

Inbound messages may carry text, file, and data parts. File and data parts are rendered into the model's context as bracketed references. Replies are text.

Authentication, rate limiting, and the trust gate answer with HTTP 401, 429, and 403; the body remains a valid JSON-RPC error envelope. A task belonging to another peer answers exactly as an absent one.

Configuration

- id: a2a-server
  name: dsh-a2a-server
  config:
    basePath: /a2a
    publicUrl: https://agents.example.com/a2a   # advertised on the card
    provider: deepseek-official
    model: deepseek-v4-flash

    card:
      name: dsh-harness
      description: Answers questions using code and text in the authorized directory.
      public: true
      skills:
        - id: general
          name: general
          description: Chat and scoped file reading.
          tags: [coding, research]
      extendedSkills:                             # authenticated peers only
        - id: internal
          name: internal diagnostics
          description: Explains project documentation from the authorized directory.
          tags: [internal]
      provider:
        organization: Example Inc.
        url: https://example.com

    peers:
      alice: { tokenEnv: A2A_PEER_ALICE }
      bob:   { tokenEnv: A2A_PEER_BOB }
    trustedPeers: [alice]
    rateLimitPerMinute: 60
    maxContextTurns: 5

    sendMode: block
    blockTimeoutMs: 60000
    contextIdleTtlMs: 1800000
    maxResidentContexts: 64

    isolation:
      workspaceMode: per-peer
      workspaceRoot: /srv/dsh/a2a
      peerWorkspaces:
        alice: /srv/project

    push:
      enabled: false
KeyDefaultMeaning
basePath/a2aJSON-RPC route
publicUrlderived from HostRoutable URL published on the card
provider · model—Model route for every agent this server creates
card.publictrueServe the card without a credential
card.skills[]Declared skills; falls back to one general entry
card.extendedSkills[]Skills revealed only through GetExtendedAgentCard
peers{}Identity → credential reference name
trustedPeersall authenticatedAccess allow-list for conversation and scoped file reads; [] denies everyone
rateLimitPerMinute60Sliding window per identity
maxContextTurns5Messages accepted per context before rejected
sendModeblockDefault when the client sends no returnImmediately
blockTimeoutMs60000Maximum blocking wait; returns the current task on timeout so the client can poll
contextIdleTtlMs1800000Idle time before a context's agent is released
maxResidentContexts64Ceiling on resident contexts
maxConcurrentTasks / maxConcurrentTasksPerPeer8 / 2Atomic task admission; excess requests receive 429
maxTasksPerPeerPerDay

Configuration is refused at load when isolation.workspaceRoot is absent, a peer name is not [A-Za-z0-9][A-Za-z0-9_-]*, a tokenEnv is not a POSIX identifier, trustedPeers or peerWorkspaces names an undeclared peer, or basePath does not start with /.

Credentials

Configuration carries credential references, never values:

peers:
  alice: { tokenEnv: A2A_PEER_ALICE }
# ~/.dsh/.credentials.yaml
refs:
  A2A_PEER_ALICE: <32-byte-hex-from-openssl-rand>

ctx.credentials resolves the reference per request across four layers — the process environment, the managed document, <cwd>/.env, and $DSH_HOME/.env — so rotating a token takes effect on the next request without a restart. Peer identity comes from the presented credential only; nothing in a request body can assert it. There is no shared bearer token: isolation is built on distinct identities.

Isolation

LayerGuaranteeMechanism
Model contextOne peer's conversation cannot enter another's model requestSeparate contextId → separate Session → separate log
Protocol accessA peer cannot read, continue, or cancel another's context or taskOwnership by authenticated identity
ToolingOnly the scoped read_file is available; no writes, shell, network or cross-session toolsInherited-tool masking, scoped reader, and execution guard
Prompt contextPublic agents have a dedicated system prompt and suppress optional host runtime contextScoped complete prompt and context suppression

Visitor working directories now live outside workspaceRoot. The selected root contains public data; read_file defaults to it and accepts root: "workspace" for the current visitor's files. Portal automatically prepares Microsandbox: one VM per visitor, read-only public projections and persistent private disks. Idle VMs pause after 30 seconds and stop after 10 minutes, retaining files. Backend conversation storage is not mounted. See setup and limits.

read_file({"path":"."}) lists the root's entries. A file path reads UTF-8 text; offset (1-based) and limit page lines or directory entries. Reads are bounded to 2 MiB files, 32,000 returned characters and 500 lines/entries per call; directory scans cover at most 1,000 entries. Binary/office-document extraction is not yet implemented. Canonical path checks refuse escapes; symlinks, junctions, hard links and Windows alternate data streams are rejected. No shell is invoked. preamble.files continues to provide an optional opening briefing.

Owner RPC uses the same /a2a path on local IPC, authenticated with the admin token. It retains the standard caretaker preset. The public HTTP listener accepts only visitor credentials and never mounts the monitoring API. See the migration and deployment notes.

Boundaries

  • Inbound only. No outbound client, peer directory, or A2A subagent provider.
  • JSONRPC binding only. gRPC and HTTP+JSON are not served, and the card says so.
  • Push notifications are not implemented. push.enabled selects which error the push methods return; the card advertises pushNotifications: false.
  • No stateTransitionHistory, protocol extensions, or card signatures.
  • Streaming emits committed assistant messages. Per-chunk streaming is not implemented.
  • Execution deadlines cancel the agent. Admission remains occupied until the underlying adapter finishes cancellation; an adapter ignoring AbortSignal needs process-level supervision. These limits are not a currency budget.
  • Only rooted read_file is enabled for visitors. Other tools require separate capability work; changing the sandbox mode does not grant those tools. This application-level file reader is not an OS sandbox against a malicious local administrator mutating the filesystem.
  • A token ceiling settles a task as completed; the real turn ending travels in Task.metadata.dsh.stopReason, which A2A's state enum cannot express.
  • Task results and idle conversation history survive eviction/restart within the retention window. Interrupted tasks become failed and are never replayed. Cold restoration creates a new harness session behind the stable contextId.
  • One task may run per context; concurrent submissions receive 409. Message IDs are not deduplication keys: proxies must not blindly retry submissions.
  • ctx.webServer provides no TLS. Any non-loopback exposure belongs behind a reverse proxy.
  • A configuration change restarts the plugin and cancels in-flight tasks.

Architecture

src/
├── protocol/          dependency-free library: no Cordis, no HTTP, no harness
│   ├── wire.ts        the A2A v1.0 vocabulary: one shape, no translation
│   ├── parse.ts       inbound parsing and the method table
│   ├── jsonrpc.ts     framing and the A2A error codes
│   ├── card.ts        Agent Card construction
│   └── sse.ts         SSE frame encoding
├── index.ts           the Cordis plugin: wiring, agent ownership, teardown
├── router.ts          HTTP + JSON-RPC dispatch, free of Cordis so it unit-tests
├── contexts.ts        contextId -> Activation registry and residency policy
├── tasks.ts           task slots and the three-stage turn correlation
├── projection.ts      the a2aTask fold over the session log
├── security.ts        authentication, rate limiting, defanging, redaction
├── workspace-read.ts  bounded read_file within the authorized data root
├── management.ts      private owner RPC and monitoring over local IPC
├── state.ts           durable task and conversation checkpoints
├── briefing.ts        hourly briefing updates and persistent scheduling
├── config.ts          schema plus the cross-field checks that fail at load
└── types.ts           declaration merges into SessionEventMap / MessageSourceMap

A task is an interval, not a turn. One submitted message may span several turns if tools queue more work, so settlement uses three hooks: agent/inbox/claimed binds the message to a turn, turn/end records that turn's ending, and agent.whenIdle() settles once the whole agent is quiet.

Task state lives in the session log. Lifecycle transitions are a2a/task events; a projection unit folds them into the read model. The terminal edge carries the committed output, so the fold serves the answer without reaching back into message history.

Residency is explicit. HTTP has no connection lifetime, so each contextId maps to an Activation evicted when idle. Private checkpoints retain task results and conversation history; cold restoration creates a new harness session.

Development

pnpm install
pnpm typecheck
pnpm test       # protocol, lifecycle, security and workspace-read regressions
pnpm serve      # a listening server
pnpm probe      # 67 checks against a running server
pnpm build      # emit lib/
pnpm test:package # verify imports with only declared runtime packages

The end-to-end suites boot a real Cordis composition with a real agent loop and drive it over HTTP, using a deterministic stub adapter so assertions do not depend on model output.

Relationship to the official project

Built against deepseek-ai/deepseek-harness.

The official project supplies the agent runtime, the plugin system, and the capability seams this plugin consumes. This project supplies:

  • The A2A v1.0 JSON-RPC binding, served inbound
  • Agent Card construction and inbound request parsing
  • Mapping between A2A tasks and harness turns
  • Per-peer authentication, isolation, and workspace policy

The harness is pre-release and does not promise compatibility across renames or repackaging, so compatibility is declared through engines.dsh (>=0.2.1-rc.2 <0.3.0) plus range-bounded @deepseek-ai/dsh-* peer dependencies: an install preflight refuses any combination the plugin was not built against, and the range admits every 0.2.x patch that follows.

Community

Scan to join the WeChat group A2A 产品应用和探索 — discussion of A2A in practice, this plugin included.

WeChat group QR code

If the code has expired, open an issue and we will refresh it.

License

MIT

Public relay integration

Talk2MyAgent Portal now supports automatic relay registration, a background Connector, publication controls and visitor invitations. This plugin continues to provide the local A2A service with its existing workspace and briefing rules. Relay is deployed independently. See implementation and tests and Portal English guide.

Relay integration test

tests/relay.integration.spec.ts is skipped unless both variables point at local checkouts:

  • A2A_RELAY_SOURCE — the a2a-relay-server repository root
  • A2A_CONNECTOR_SOURCE — Talk2MyAgent's packages/a2a-connector directory (run pnpm install in Talk2MyAgent first)
A2A_RELAY_SOURCE=/path/to/a2a-relay-server \
A2A_CONNECTOR_SOURCE=/path/to/Talk2MyAgent/packages/a2a-connector \
pnpm vitest run tests/relay.integration.spec.ts

It uses a stub model, temporary data and dynamic ports; no API key or DSH install is needed.

200
Persisted task allowance per identity per UTC day
taskTimeoutMs120000Cancels execution when its deadline expires
maxModelCallsPerTask / maxOutputTokens8 / 4096Model request and per-request output limits
maxInputChars / maxOutputChars32000 / 64000Input/output text limits
streamHeartbeatMs / maxStreamsPerTask15000 / 4Heartbeat interval and subscription cap
maxStreamBufferBytes262144Disconnect a stream whose buffered frame exceeds the cap
storage.directory~/.dsh-a2a/<deployment-key>Private checkpoints; one process per directory
storage.retentionMs / storage.maxContexts86400000 / 256Retention after last activity, and maximum stored contexts
storage.maxContextBytes4000000Maximum checkpoint bytes per context
isolation.workspaceModeper-peerLegacy migration field; visitors now have an external private cwd
isolation.workspaceRoot—Required; shared public read-only data root
isolation.peerWorkspaces{}Legacy per-identity read-root override
isolation.privateRootdeployment-specific home directoryPrivate workspace parent, outside public data
isolation.executionread-onlySelect microsandbox for per-visitor VMs (Portal default); legacy docker also supported
preamble.files[".hop/handoff.md"]Host briefing files (agent-level: resolved against the workspace root and shared by every visitor; absolute paths pass through), merged into each context's first message; absent files are skipped
briefing.prompt—Optional single-update instruction executed as the bounded local owner at startup and hourly; configured by Portal, requires owner administration
briefing.settingsFile—Absolute path to a JSON { "enabled": boolean } preference; absent file means enabled, observed every 5 seconds. Disabling preserves the current briefing and lets active work finish; restart timing is persisted
admin.tokenEnv—Credential reference for local owner and monitoring requests; rejected by public RPC
admin.socketPathdeployment-specificWindows named pipe or private Unix socket for owner RPC and monitoring
push.enabledfalseReserved; see Boundaries